#coding:utf8
from PyQt5.QtWidgets import * 
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import random
from pynput.keyboard import Key, Listener
from pynput import keyboard,mouse
from pynput import keyboard
import math
import threading
import logging,datetime
import sys
import time
import functools
import threading
from collections import deque
from logging.handlers import RotatingFileHandler
import os
import redis

pattern_txt = ''
loger = logging.getLogger("basic")
loger.setLevel(logging.INFO)
handler2 = RotatingFileHandler('mfli2.log', maxBytes=3*1024*1024,
                              backupCount=1)
loger.addHandler(handler2)
loger.warning(str(datetime.datetime.now())+"   starts")

def get_sta():
    fs = 'mouse:{total[%s %ss] draw_counts[%s] kb[%s %ss] | acc[%s %ss] no_acc[%s %ss] '+\
        '| jump[%s %ss] no_jump[%s %ss] | kb-mouse[%s %ss]}    press+clicks[%s %ss] total[%ss]'
    
    s = fs%(total_g['moves'],total_g['time'],draw_counts,
          total_g_keyboard['moves'],total_g_keyboard['time'],
          total_g_mouse_acc['moves'],total_g_mouse_acc['time'],
          total_g_mouse_no_acc['moves'],total_g_mouse_no_acc['time'],
          total_g_mouse_jump['moves'],total_g_mouse_jump['time'],
          total_g_mouse_no_jump['moves'],total_g_mouse_no_jump['time'],
          mouse_from_socket_counts['moves'],mouse_from_socket_counts['time'],
          key_press_counts['moves'],key_press_counts['time'],
          kb_mouse_total['time'])
    
    return s
    
def do_loger():
    s = get_sta()
    loger.warning(str(datetime.datetime.now())+"  "+s)
        
info_logger = logging.getLogger("verbose")
info_logger.setLevel(logging.INFO)
handler = RotatingFileHandler('mfli2_verbose.log', maxBytes=5*1024*1024,
                              backupCount=2)
info_logger.addHandler(handler)

if getattr(sys, 'frozen', False):
    application_path = os.path.dirname(sys.executable)
elif __file__:
    application_path = os.path.dirname(__file__)
    if not application_path:
        application_path = os.getcwd()

print ("application_path",application_path)

##############################
#flags

draw_counts = 0
caps_mode = False
last_caps_mode = False
has_other_when_caps = False
is_cap_pressed = False

if os.name=='nt':      
    from winreg import*
    import winreg
    import os,sys
    import subprocess


def read_reg(path, root=HKEY_CURRENT_USER):
    path, name = os.path.split(path)
    with  OpenKey(root, path) as key:
        x = QueryValueEx(key, name)
    return x[0]
        
def write_reg(path, value, root=HKEY_CURRENT_USER):
    path, name = os.path.split(path)
    with OpenKey(root, path, 0, KEY_WRITE) as key:
        SetValueEx(key, name, 0, REG_SZ, value)
        
ps1 = '''
$f=@'
[DllImport("user32.dll")]public static extern int SystemParametersInfo(
    int uAction, 
    int uParam, 
    IntPtr lpvParam, 
    int fuWinIni
);
'@

$mSpeed = Add-Type -memberDefinition $f -name "mSpeed" -namespace Win32Functions -passThru
[IntPtr]$srcSpeedPtr = [system.runtime.interopservices.marshal]::AllocHGlobal(4)
$mSpeed::SystemParametersInfo(0x0057,0,$srcSpeedPtr,0)
'''
f = open("%s/cursor.ps1"%application_path,'w')
f.write(ps1)
f.close()

f=open(r"%s\cursor.bat"%application_path,'w')
f.write('powershell.exe '+r"%s\cursor.ps1"%application_path)
f.close()

def make_cursor_effect():
    subprocess.call(r"%s\cursor.bat"%application_path, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)            
hidden_cursor = ''
def show_cursor():    
    if os.name!='nt':      
        return    
    global hidden_cursor
    try:
        a = read_reg(r'Control Panel\Cursors\Arrow')    
        if not hidden_cursor:
            hidden_cursor = a
        
        if not a:
            hidden_cursor = a
            
        a = write_reg(r'Control Panel\Cursors\Arrow','')    
        a = write_reg(r'Control Panel\Cursors\IBeam','')    
        a = write_reg(r'Control Panel\Cursors\Hand','')    
        make_cursor_effect()
    except:
        pass

def hide_cursor():
    if os.name!='nt':      
        return
    try:
        a = write_reg(r'Control Panel\Cursors\Arrow',hidden_cursor)    
        a = write_reg(r'Control Panel\Cursors\IBeam',hidden_cursor)    
        a = write_reg(r'Control Panel\Cursors\Hand',hidden_cursor)
        make_cursor_effect()    
    except:
        pass

def reset_cap():
    if is_cap_pressed:
        return
    global caps_mode
    caps_mode = False    
    
def set_has_other_when_caps():
    global has_other_when_caps
    if is_cap_pressed and not has_other_when_caps:
        show_cursor()     
    has_other_when_caps = True
        
def caps_press():
    global caps_mode,has_other_when_caps,last_caps_mode,is_cap_pressed
    if is_cap_pressed:
        return
    is_cap_pressed = True
    last_caps_mode = caps_mode
    caps_mode = True    
    has_other_when_caps = False

def caps_release():
    global caps_mode,is_cap_pressed
    is_cap_pressed = False
    if has_other_when_caps:
        caps_mode = False
    else:
        caps_mode = not last_caps_mode    
    if seek_mode==5 or seek_mode==7:
        return
    if caps_mode:
        show_cursor()
    else:
        hide_cursor()

    
force_acc_when_fast = False
def set_force_acc_when_fast():
    global force_acc_when_fast
    force_acc_when_fast = not force_acc_when_fast

force_acc_when_all = False
def set_force_acc_when_all():
    global force_acc_when_all
    force_acc_when_all = not force_acc_when_all

force_acc_when_middle = False
def set_force_acc_when_middle():
    global force_acc_when_middle
    force_acc_when_middle = not force_acc_when_middle

seek_mode = 1
show_seek_mode = False
def set_show_seek_mode():
    global show_seek_mode
    show_seek_mode = not show_seek_mode
    
show_speed_icon = True
fix_mouse_speed = False

def set_fix_mouse_speed():
    global fix_mouse_speed
    fix_mouse_speed = not fix_mouse_speed
    
def set_show_speed():
    global show_speed_icon
    show_speed_icon = not show_speed_icon
    	
mouse_current_speed = -1

mouse_slow = False
mouse_slow_speed = 4
mouse_fast_speed = 11
mouse_fast_speed_no_acc = 14
no_acc = True

rec_w = 0
rec_h = 0


remote_gap_move_x_remains = 0
remote_gap_move_y_remains = 0
remote_gap_move_x_gap = 1
remote_gap_move_y_gap = 1
remote_gap_move_time = 0
remote_gap_move_on = False
remote_gap_move_new_x = 0
remote_gap_move_new_y = 0
remote_gap_move_scale = [3,1,0,3,1]

def set_remote_gap_move_scale():    
    p = '%s/../remote_gap_scale.json'%application_path
    f = open(p)
    j = json.load(f)
    f.close()
    for i in range(5):
        remote_gap_move_scale[i] = float(j[i])
    print('remote_gap_move_scale',remote_gap_move_scale)
    
def set_remote_gap():
    global remote_gap_move_on
    remote_gap_move_on = not remote_gap_move_on
    try:
        set_remote_gap_move_scale()
    except:
        print('set_remote_gap_move_scale err')        
    
def clear_remote_gap_move():
    global remote_gap_move_x_remains,remote_gap_move_y_remains,remote_gap_move_new_x,remote_gap_move_new_y
    remote_gap_move_y_remains = 0
    remote_gap_move_x_remains = 0
    remote_gap_move_new_x = 0
    remote_gap_move_new_y = 0
    

def remote_gap_move(dx2,dy2):
    global remote_gap_move_x_remains,remote_gap_move_y_remains,remote_gap_move_time    
    global remote_gap_move_new_x,remote_gap_move_new_y
    remote_gap_move_time = time.time()
    
    if  not remote_gap_move_on:                                  
        mouse.Controller().move(dx2,dy2)
        return
    scale = 0
    if alt_pressed or alt_r_pressed:
        scale = remote_gap_move_scale[0]
    elif ctrl_pressed or ctrl_r_pressed:                        
        scale = remote_gap_move_scale[1]
    elif shift_pressed or shift_r_pressed :
        scale = remote_gap_move_scale[2]
    elif gear_on and gmw_g.gear_mode==2:
        scale = remote_gap_move_scale[4]
    else:
        scale = remote_gap_move_scale[3]
    if scale<=0:
        mouse.Controller().move(dx2,dy2)
        return
    
    remote_gap_move2_x_gap = max(1,round(remote_gap_move_x_gap*scale))
    remote_gap_move2_y_gap = max(1,round(remote_gap_move_y_gap*scale))        
        
    remote_gap_move_x_remains += dx2
    remote_gap_move_y_remains += dy2
    remote_gap_move_new_x+= dx2
    remote_gap_move_new_y += dy2
    
        
    if not (abs(remote_gap_move_new_x)>=remote_gap_move2_x_gap or abs(remote_gap_move_new_y)>=remote_gap_move2_y_gap):    
        return
    
    tx = ty = 0
    
    while abs(remote_gap_move_x_remains)>=remote_gap_move2_x_gap or abs(remote_gap_move_y_remains)>=remote_gap_move2_y_gap:
        if abs(remote_gap_move_x_remains)>= remote_gap_move2_x_gap:
            dx = remote_gap_move2_x_gap
            if remote_gap_move_x_remains<0:
                dx = -dx                
            dy = 0
            if abs(remote_gap_move_y_remains)>=remote_gap_move2_y_gap/5*4:
                dy = remote_gap_move2_y_gap
                if remote_gap_move_y_remains<0:
                    dy = -dy
            remote_gap_move_x_remains -= dx
            remote_gap_move_y_remains -= dy
            tx += dx
            ty+= dy                        
            continue
        
        if abs(remote_gap_move_y_remains)>= remote_gap_move2_y_gap:
            dy = remote_gap_move2_y_gap
            if remote_gap_move_y_remains<0:
                dy = -dy
            dx = 0
            if abs(remote_gap_move_x_remains)>=remote_gap_move2_x_gap/5*4:
                dx = remote_gap_move2_x_gap
                if remote_gap_move_x_remains<0:
                    dx = -dx
            remote_gap_move_x_remains -= dx
            remote_gap_move_y_remains -= dy
            tx += dx
            ty+= dy                                                    
            continue        
    
    
    dstx = x_g+tx
    dsty = y_g+ty
    
    if scale>=2:
        dstx = find_near_mod(dstx, remote_gap_move2_x_gap)
        dsty = find_near_mod(dsty, remote_gap_move2_y_gap)
    
    dx = dstx-x_g
    dy = dsty-y_g    
    print('y_g ty dsty dy',y_g,ty,dsty,dy)
    remote_gap_move_x_remains += (tx-dx)
    remote_gap_move_y_remains += (ty-dy)    
    if dx!=0 or dy!=0:
        remote_gap_move_new_x = remote_gap_move_new_y = 0            
        mouse.Controller().move(dstx-x_g,dsty-y_g)        
        if scale>=3:
            if dx!=0:
                remote_gap_move_x_remains = 0
                if remote_gap_move_y_remains<remote_gap_move2_y_gap/2:
                    remote_gap_move_y_remains = 0
            if dy!=0:
                remote_gap_move_y_remains = 0    
                if remote_gap_move_x_remains<remote_gap_move2_x_gap/2:
                    remote_gap_move_x_remains = 0
                
    

def set_no_acc():
    global no_acc
    no_acc = not no_acc
    
mouse_speed_mode = 2

if os.name=='nt':      
    import win32gui
    import win32con
sys_last_speed = -1

mode2_and_acc_sign = True
fresh_when_acc = False
fresh_gap_on = False

show_anchor = [False,False,False]
def set_show_anchor(n):    
    show_anchor[n] = not show_anchor[n]
    
show_xy = False
show_xy_print = False
show_xy_insert = False
def set_show_xy():
    global show_xy
    show_xy = not show_xy
def set_show_xy_print():
    global show_xy_print
    show_xy_print = not show_xy_print    

def set_show_xy_insert():
    global show_xy_insert
    show_xy_insert = not show_xy_insert
    
show_xy2 = False
def set_show_xy2():
    global show_xy2
    show_xy2 = not show_xy2

show_xy3 = False
def set_show_xy3():
    global show_xy3
    show_xy3 = not show_xy3
    
def set_fresh_gap_on():
    global fresh_gap_on
    fresh_gap_on = not fresh_gap_on
    
def set_fresh_when_acc():
    global fresh_when_acc
    fresh_when_acc = not fresh_when_acc

slow_jump = False 
def set_slow_jump():
    global slow_jump
    slow_jump = not slow_jump
    

is_sys_acc = False
acc_no_fresh_sign = False

def sys_set_mosue_speed(n,mode,set_acc=False):
    print('sys_set_mosue_speed',set_acc)
    global sys_last_speed,mode2_and_acc_sign,acc_no_fresh_sign
    if fix_mouse_speed:
        return
    if n == sys_last_speed:
        return
    sys_last_speed = n
    if os.name!='nt':      
        return        
    win32gui.SystemParametersInfo(win32con.SPI_SETMOUSESPEED,n,0)     
    
    to_set = False
    if mode == 1 and force_acc_when_all:
        to_set = True
    if mode == 3 and force_acc_when_fast:
        to_set = True
    if mode == 4 and force_acc_when_middle:
        to_set = True        
    
    mode2_and_acc_sign = mode==2    
    
    acc_no_fresh_sign = False
    global is_sys_acc        
    if set_acc or to_set:             
        win32gui.SystemParametersInfo(win32con.SPI_SETMOUSE,(6,10,1))     
        acc_no_fresh_sign = True
        is_sys_acc = True
        if fresh_when_acc:            
            print('fresh_when_acc',mode2_and_acc_sign)
            acc_no_fresh_sign = False
        
    else:                
        win32gui.SystemParametersInfo(win32con.SPI_SETMOUSE,(0,0,0))                 
        is_sys_acc = False
    
def set_mouse_speed():
    global mouse_current_speed,mouse_speed_mode    
    if mouse_slow:
        sys_set_mosue_speed(mouse_slow_speed,1)        
        mouse_current_speed = mouse_slow_speed
        mouse_speed_mode = 1
    else:
        if no_acc:
            sys_set_mosue_speed(mouse_fast_speed_no_acc,2,False)                
            mouse_current_speed = mouse_fast_speed_no_acc
        else:                                    
            sys_set_mosue_speed(mouse_fast_speed,2,True)                
            mouse_current_speed = mouse_fast_speed
        mouse_speed_mode = 2


togg_mouse_normal = set()
togg_mouse_co = 0

togg_mouse_speed_last = False
def clear_togg_mouse_speed():
    global togg_mouse_co,togg_mouse_normal
    togg_mouse_normal = set()
    togg_mouse_co = 0
    
def togg_mouse_speed():    
    global mouse_slow,togg_mouse_speed_last,togg_mouse_speed_job    
    global togg_mouse_co,togg_mouse_normal
    global alt_r_pressed,ctrl_r_pressed,shift_r_pressed
    
    print('togg_mouse_speed 22')
    if gear_on and gmw_g.gear_mode != 0:
        gmw_g.gear_mode = 0
        return
        
    if (not fix_mouse_speed and len(togg_mouse_normal)<2) or ( fix_mouse_speed and len(togg_mouse_normal)==0):
        fix_not_return = False
        if mouse_speed_mode in (1,2):
            togg_mouse_normal.add(mouse_slow)
            if not fix_mouse_speed:            
                mouse_slow = not mouse_slow
            else:
                fix_not_return = True
            togg_mouse_speed_last = mouse_slow            
            
        else:
            mouse_slow = togg_mouse_speed_last
        togg_mouse_normal.add(mouse_slow)            
        set_mouse_speed()    
        clear_r_pressed(True)        
        if not fix_not_return:
            return        
    
    clear_r_pressed(False)
    togg_mouse_co += 1
    if togg_mouse_co==1:
        alt_r_pressed = True
    if togg_mouse_co==2:
        ctrl_r_pressed = True
    if togg_mouse_co==3:
        clear_togg_mouse_speed()
        shift_r_pressed = True                        
    set_r_ms()         

alt_r_pressed = False
ctrl_r_pressed = False
shift_r_pressed = False

alt_r_ms = 19
ctrl_r_ms = 12
shift_r_ms = 2

r_has_effect = False
def set_r_ms():
    global mouse_current_speed,mouse_speed_mode
    global mouse_slow,r_has_effect    
    has_pressed = alt_pressed or alt_r_pressed or shift_pressed or \
        shift_r_pressed or ctrl_pressed or ctrl_r_pressed
    
    if r_has_effect and not fix_mouse_speed:
        r_has_effect = False        
    
    if not has_pressed:
        set_mouse_speed()
        return
    
    mm = {'alt':3,'ctrl':4,'shift':5}
    for i,mode in [('shift',5),('ctrl',4),('alt',3)]:        
        if globals()[i+'_pressed']:
            if not fix_mouse_speed:
                sys_set_mosue_speed(globals()[i+'_r_ms'],mode)            
            mouse_current_speed = globals()[i+'_r_ms']
            mouse_speed_mode = mm[i]
            return
    for i,mode in [('shift',5),('ctrl',4),('alt',3)]:            
        if globals()[i+'_r_pressed']:
            if not fix_mouse_speed:
                sys_set_mosue_speed(globals()[i+'_r_ms'],mode)            
            mouse_current_speed = globals()[i+'_r_ms']
            mouse_speed_mode = mm[i]
            return
        
def clear_r_pressed(need_set_speed = True):        
    global alt_r_pressed,ctrl_r_pressed,shift_r_pressed,pattern_is_moving
    gmw_g.gear_mode = 0
    pattern_is_moving = False
    if need_set_speed:
        set_mouse_speed()
    alt_r_pressed = False
    ctrl_r_pressed = False
    shift_r_pressed = False

doublem30indx = 0
change_speed_time = 0

def change_speed_indx():
    global doublem30indx,alt_r_pressed,ctrl_r_pressed,shift_r_pressed,change_speed_time
    change_speed_time = time.time()
    clear_r_pressed(False)
    doublem30indx += 1
    print('doublem30indx',doublem30indx)
    if doublem30indx%3==1:
        alt_r_pressed = True
    if doublem30indx%3==2:
        ctrl_r_pressed = True
    if doublem30indx%3==0:
        shift_r_pressed = True                        
    set_r_ms()    
    
def is_r_pressed():
    return alt_r_pressed or ctrl_r_pressed or shift_r_pressed

has_other_clicks = False
has_other_clicks_from_mouse = False

def set_r_sign():
    global has_other_clicks,has_other_clicks_from_mouse
    has_other_clicks = False
    has_other_clicks_from_mouse = False    
    
def is_r_single_clicked():
    return (not has_other_clicks) and (not has_other_clicks_from_mouse)

def is_r_single_clicked_mouse():    
    return (not has_other_clicks_from_mouse)

def has_keyboard_clicks():
    return has_other_clicks

def set_r_other_clicks(is_from_mouse = False):
    global has_other_clicks,has_other_clicks_from_mouse
    if not is_from_mouse:
        has_other_clicks = True
    else:
        has_other_clicks_from_mouse = True
        
random_jump = 0
def set_random_jump(n):
    global random_jump
    random_jump = n
    
hide_cursor_when_move = False
def set_hide_cursor_when_move():
    global hide_cursor_when_move
    hide_cursor_when_move = not hide_cursor_when_move
    
remote_mouse_right_pressed = False

show_up_mouse= True
show_down_mouse= True
def set_show_up_mouse():
    global show_up_mouse
    show_up_mouse = not show_up_mouse
def set_show_down_mouse():
    global show_down_mouse
    show_down_mouse = not show_down_mouse

to_active = False
def set_to_active():
    global to_active
    to_active = True

win4_refresh_gap_10ms = 9
speed_thres = 400
speed_thres_min = 200

def set_win4_refresh_gap_10ms(n,thr,thr2):
    global win4_refresh_gap_10ms,speed_thres,speed_thres_min
    win4_refresh_gap_10ms = n
    speed_thres = thr
    speed_thres_min = thr2


remote_mouse_force_smooth = False
mouse_force_smooth = False
socket_mouse_time = 0
def set_remote_mouse_force_smooth():
    global remote_mouse_force_smooth
    remote_mouse_force_smooth = not remote_mouse_force_smooth

def set_mouse_force_smooth():
    global mouse_force_smooth
    mouse_force_smooth = not mouse_force_smooth
    
draw_mouse_when_off = True

def change_draw_mouse_when_off():
    global draw_mouse_when_off
    draw_mouse_when_off = not draw_mouse_when_off

draw_mouse_rec = True
def set_draw_mouse_rec():
    global draw_mouse_rec
    draw_mouse_rec = not draw_mouse_rec

ctrl_pressed = False
shift_pressed = False
alt_pressed = False

force_not_show = False
force_not_show_set_time = 0

def set_force_not_show(): #强制临时不显示。历史功能。现在不会触发。                   
    global force_not_show,force_not_show_set_time                    
    force_not_show = True
    force_not_show_set_time = time.time()
    
keyboard_input_on = True
mouse_input_on = True

def toggk():
    redis.Redis('127.0.0.1').delete(str(listen_port2))    
    global keyboard_input_on
    keyboard_input_on = not keyboard_input_on

def toggm():
    redis.Redis('127.0.0.1').delete(str(listen_port))
    global mouse_input_on
    mouse_input_on = not mouse_input_on

mouse_rec_full_line = True
def change_full_line():
    global mouse_rec_full_line
    mouse_rec_full_line = not mouse_rec_full_line

hide_rec_when_kb = False
def set_hide_rec_kb():
    global hide_rec_when_kb 
    hide_rec_when_kb = not hide_rec_when_kb 
    
gear_scro = False
def set_gear_scro():
    global gear_scro
    gear_scro = not gear_scro
    
#鼠标移动总数
total_g = {'moves': 0,'time':0,'last':0}
total_g_keyboard = {'moves': 0,'time':0,'last':0}
total_g_mouse_no_acc = {'moves': 0,'time':0,'last':0}
total_g_mouse_acc = {'moves': 0,'time':0,'last':0}
total_g_mouse_jump = {'moves': 0,'time':0,'last':0}
total_g_mouse_no_jump = {'moves': 0,'time':0,'last':0}
key_press_counts = {'moves': 0,'time':0,'last':0}
kb_mouse_total = {'moves': 0,'time':0,'last':0}
mouse_from_socket_counts = {'moves': 0,'time':0,'last':0}


def update_sta(m,add_moves=True):
    if add_moves:
        m['moves'] += 1
    if int(time.time()) == m['last']:
        return
    m['last'] = int(time.time()) 
    m['time'] += 1    


g_grab_pos = None
speed_mode = True
fix_mode = False
has_fixed_mouse = True
has_fixed_mouse2 = True

def set_fix_mode():
    global fix_mode
    fix_mode = not fix_mode
    
def set_speed_mode():    
    global speed_mode
    speed_mode = not speed_mode
    
last_grab_time = 0

def set_grab():
    global last_grab_time
    last_grab_time = time.time()
    
def check_grab_show_times():    
    thistime = time.time()-last_grab_time    
    return thistime > 0.08

manul_mosue_time = 0 
inner_step = 1
fixed_inner_step = False

def set_inner_step(n,from_btn=False):
    global inner_step,fixed_inner_step
    if from_btn:
        if n<0:
            fixed_inner_step = True
            inner_step = 1
            return
        else:
            fixed_inner_step = False
    if not fixed_inner_step:
        inner_step = n
to_quit = False
rec_pos = [0,0]
grab_pos = []
force_change = False
fix_gap = False


##############################
#constans in script, can not change runtime
#外部控制鼠标的相关参数，在发送程序（vm-share/c.py）中修改

#ctrl 加速倍数
ctrl_speed = 3
#shift 加速倍数
alt_speed = 11


#socket操作鼠标至少显示时间
manul_show_time = 3

config_path = '%s/../mfli2_conf.txt'%application_path

#左上角留空白尺寸
xxiu = 20
yxiu = 60
#截图框尺寸
gg_size = 3

#窗口大小留白
window_geo_gap = 50

#窗口偏移留白
window_pos_gap = 8
listen_port = 33445
listen_port2 = 33446
g_txt_pos = (35,30)
g_txt_size = (170,20)

#是否变换位置时判断的留白
check_geom_gap = 10

#第二个窗口的大小
window2_size = 200

#第二个窗口左上留白
window2_left = 60

#鼠标框位置、尺寸
mouse_rec_in = (3,8,3)
mouse_rec_out = (1,12,1)

#鼠标模式 大小和偏移
mouse_cursor_m = [('arrow_m.cur',32,32,(-5,-16),(-2,1),'arrow_r.cur'),
                  ('aero_arrow.cur',32,32,(-5,-16),(-1,5),'aero_unavail_xl.cur'),
                  ('arrow_r.cur',32,32,(-5,-16),(-1,4),'aero_arrow.cur')
                  ]
mouse_cursor_idx=0

mouse_cursor_pixmap = None
mouse_cursor_pixmap2 = None
mouse_cursor_pixmap3 = None
mouse_cursor_pos1 = None
mouse_cursor_pos2 = None
mouse_cursor_size = None
mouse_cursor_size2 = None
mouse_cursor_rec = None
mouse_cursor_rec2 = None
mouse_cursor_rec3 = None
mouse_cursor_rec4 = None

def change_mouse_cursor():
    global mouse_cursor_idx,mouse_cursor_pixmap,mouse_cursor_pos1,mouse_cursor_pixmap3, \
    mouse_cursor_pos2,mouse_cursor_size,mouse_cursor_size2,mouse_cursor_pixmap2,mouse_cursor_rec
    global mouse_cursor_rec2,mouse_cursor_rec3,mouse_cursor_rec4
    
    f = 'up_l.cur'
    if not os.path.isfile('%s/%s'%(application_path,f)):
        f = '%s/../%s'%(application_path,f)
    else:
        f = '%s/%s'%(application_path,f)
    icon_g = QIcon(f)    
    mouse_cursor_rec0 = icon_g.pixmap(icon_g.actualSize(QSize(32, 32)))
    
    rm = QTransform()
    rm.rotate(0);
    mouse_cursor_rec = mouse_cursor_rec0.transformed(rm);
    
    rm = QTransform()
    rm.rotate(90);
    mouse_cursor_rec2 = mouse_cursor_rec0.transformed(rm);

    rm = QTransform()
    rm.rotate(180);
    mouse_cursor_rec3 = mouse_cursor_rec0.transformed(rm);
    rm = QTransform()
    rm.rotate(270);
    mouse_cursor_rec4 = mouse_cursor_rec0.transformed(rm);
        
    #f = 'size1_rm.cur'
    #if not os.path.isfile('%s/%s'%(application_path,f)):
        #f = '%s/../%s'%(application_path,f)
    #else:
        #f = '%s/%s'%(application_path,f)
    #icon_g = QIcon(f)     
    #mouse_cursor_rec2 = icon_g.pixmap(icon_g.actualSize(QSize(32, 32)))    
    
    mouse_cursor_idx += 1
    if mouse_cursor_idx==len(mouse_cursor_m):
        mouse_cursor_idx = 0
    f,mouse_cursor_size, mouse_cursor_size2,mouse_cursor_pos1,mouse_cursor_pos2 ,f2= mouse_cursor_m[mouse_cursor_idx]
    if not os.path.isfile('%s/%s'%(application_path,f)):
        f = '%s/../%s'%(application_path,f)
    else:
        f = '%s/%s'%(application_path,f)
    icon_g = QIcon(f)     
    mouse_cursor_pixmap = icon_g.pixmap(icon_g.actualSize(QSize(mouse_cursor_size, mouse_cursor_size)))
    icon_g = QIcon(f)     
    mouse_cursor_pixmap2 = icon_g.pixmap(icon_g.actualSize(QSize(mouse_cursor_size2, mouse_cursor_size2)))
    if not os.path.isfile('%s/%s'%(application_path,f2)):
        f2 = '%s/../%s'%(application_path,f2)
    else:
        f2 = '%s/%s'%(application_path,f2)
    icon_g = QIcon(f2)     
    mouse_cursor_pixmap3 = icon_g.pixmap(icon_g.actualSize(QSize(mouse_cursor_size2, mouse_cursor_size2)))

#鼠标模式，第二个window大小
window2_size_mouse_mode = 180
#鼠标与放大框距离小于此，则移动放大框
move_thres = 115

##########################################################
#constans in config json,can not change runtime

#显示器尺寸
screen_config = [(0,0,1366,768),(1367,0,1920,1080)]
has_r_win = False
screen_lable_font = [10,9]
screen_move_len = [(17,45,0.75),(30,70,1.25)]
dst_bigger = 3
#截图尺寸
plen = 90
socket_secret = 'zytx123'

gap_g_const = 1  #show time

alt_gap_times = 1
ctrl_gap_times = 1

def get_gap_g_const():    
    return gap_g_const

import json,os
scale_2nd_ori = [0.8,2.5,0.2,2.5,0.8]
scale_2nd = scale_2nd_ori
gear_v_ori = [60,0.2,0.4,2.5,0.2]
gear_v = gear_v_ori  #距离，时间阈值，失效等待时间，快速模式速度，快速模式失效时间。慢速模式使用的是2nd_scale的第一个速度。

gear_on = True
gear_last_move_time = 0
gear_change_time = 0
gear_mode_var = 0 # 0无，1速度选择，2慢，3快
gear_cur_pos = [0,0]
gear_start_time = 0

class gear_mode_wapper:
    @property
    def gear_mode(self):
        global gear_mode_var        
        return gear_mode_var
    @gear_mode.setter
    def gear_mode(self,new_price):
        global gear_mode_var,pattern_is_moving
        if (new_price==2 and gear_mode_var!=2) or (new_price!=2 and gear_mode_var==2): 
            clear_remote_gap_move()
            pattern_is_moving = False
            print('pattern_is_moving',pattern_is_moving,new_price,time.time())
        gear_mode_var = new_price        
        
gmw_g = gear_mode_wapper()

is_type2 = False
second_mouse_scale = [1,1,1,1,1,1,1]
def save_config():    
    try:        
        m= {'screen_config':screen_config,'screen_lable_font':screen_lable_font,
            'screen_move_len':screen_move_len,
            'dst_bigger':dst_bigger,'plen':plen,'socket_secret':socket_secret,
            'gap_g_const':gap_g_const,
            'alt_ctrl_shift_speed':[alt_r_ms,ctrl_r_ms,shift_r_ms], 
             'slow_fast_fastnoacc_speed':[mouse_slow_speed,mouse_fast_speed,mouse_fast_speed_no_acc],
             'gap_times_alt_ctrl':[alt_gap_times,ctrl_gap_times],
             'refresh_gap':[win4_refresh_gap_10ms,speed_thres,speed_thres_min],
             'has_r_win':has_r_win,
             'scale_2nd':second_mouse_scale[:len(scale_2nd)],"is_type2":is_type2,
             'gear_v':gear_v
            }
        f = open(config_path,'w')
        json.dump(m,f,indent=4)
        f.close()
    except Exception as e:
        loger.error(str(e))
        print(e)
if not os.path.isfile(config_path):
    save_config()
    
ini_config_ok = True        
pattern_v = [1,-1,0.5,0.4,150,5] #是否开启，是否在托盘提示，间隔阈值，判断时间阈值，判断距离阈值(最大，最小)
pattern_is_moving = False
pattern_start_time = 0
pattern_start_pos = [0,0]
pattern_last_move_time = 0
pattern_max_dis = 0

try:
    f = open(config_path)    
    j =json.load(f)
    f.close()
    screen_config = j['screen_config']
    screen_lable_font = j['screen_lable_font']
    screen_move_len = j['screen_move_len']
    dst_bigger = j['dst_bigger']
    plen = j['plen']
    socket_secret = j['socket_secret']
    if 'gap_g_const' in j:
        gap_g_const =j['gap_g_const']    
    if 'alt_ctrl_shift_speed' in j:
        alt_r_ms,ctrl_r_ms,shift_r_ms = j['alt_ctrl_shift_speed']
    if 'slow_fast_fastnoacc_speed' in j:
        mouse_slow_speed,mouse_fast_speed,mouse_fast_speed_no_acc = j['slow_fast_fastnoacc_speed']
    if 'gap_times_alt_ctrl' in j:
        alt_gap_times,ctrl_gap_times =j['gap_times_alt_ctrl']
    if 'refresh_gap' in j:
        win4_refresh_gap_10ms,speed_thres,speed_thres_min = j['refresh_gap']
    has_r_win = j.get('has_r_win',False)
    scale_2nd = j.get('scale_2nd',scale_2nd_ori)
    is_type2 = j.get('is_type2',False)
    gear_v = j.get('gear_v',gear_v_ori)
    if len(gear_v) != 5:
        gear_v = gear_v_ori        
except Exception as e:
    loger.error(str(e))
    print(e)
    ini_config_ok = False

print('config',screen_config)

lock = threading.Lock()
redis_conn = redis.Redis('127.0.0.1')

def send(ss):    
    try:
        r = str(listen_port)+'re'
        with lock:
            redis_conn.rpush(r,socket_secret+ss)            
    except Exception as e:
        print(e)
def send_gear():    
    if  gear_on and gmw_g.gear_mode in [0,1] and mouse_speed_mode in [1,2]:
        if gear_v[4]>=0.199:
            send('gear_on')
            return
        if pattern_v[0]>0:
            if not pattern_is_moving :                
                send('gear_on')
                return                                
            if time.time()-pattern_start_time<pattern_v[3] and pattern_max_dis<pattern_v[4]:
                send('gear_on')
                return                
    send('gear_off')
        
def gear_thr_fun():
    while True:
        time.sleep(0.05)
        send_gear()
            
gear_thr = threading.Thread(target=gear_thr_fun)
gear_thr.setDaemon(True)
gear_thr.start()
        
sys_set_mosue_speed(mouse_fast_speed,mouse_speed_mode,True)

##########################################################
#constans that can be changed in runtime

pleny = 0
bigger_times =0 
geox = 0
geoy = 0
geogx_const = 0
geogy_const = 0
geochx_const = 0
geochy_const =0 
changeG = 0
changeGx = 0

def reset_config(x=-1):            
    global pleny,bigger_times,geox,geoy,geogx_const,geogy_const,geochx_const,geochy_const,changeG,changeGx,dst_bigger
    if x>=0:
        dst_bigger = x
    pleny = round(plen*0.618)    
    coff = dst_bigger/4    
    #放大倍数
    bigger_times = round(4*coff)        
    #窗口尺寸
    geox = xxiu+bigger_times*(plen)+window_geo_gap
    geoy = yxiu+bigger_times*(pleny)+window_geo_gap    
    #窗口相对于鼠标位置的偏移
    geogx_const = -(xxiu+bigger_times*(plen)+round((plen+2*gg_size)/0.618)+(plen+2*gg_size)//2+window_pos_gap)
    geogy_const = -(yxiu+bigger_times*(pleny)+round((pleny+2*gg_size)/0.618)+(pleny+2*gg_size)//2+window_pos_gap)    
    #变化位置时窗口相对于鼠标位置的偏移
    geochx_const = -xxiu+round((plen+2*gg_size)/0.618)+(plen+2*gg_size)//2+window_pos_gap
    geochy_const = -yxiu+round((pleny+2*gg_size)/0.618)+(pleny+2*gg_size)//2+window_pos_gap        
    #截图变化时坐标点的移动距离（负相关）
    changeG = round(pleny*0.618)
    changeGx = round(plen*0.618)
    
reset_config()

############################

#globals

fix_geo = False
def change_fix_geo():
    global fix_geo
    fix_geo = not fix_geo
    
#窗口跟随
step_mode = False
show_big_color = True
show_txt = True
show_draw = True
is_pressed = False

#画红绿蓝时的点阵
mm = {}
ll = []
for i in range(10):
    for j in range(30):
        ll.append((i,j))
for i in range(0,257):
    mm[i] = random.choices(ll,k=i)
    mm[i] = ll[:i]

#鼠标位置
x_g = 0
y_g = 0

#鼠标速度相关
x_step = 0
y_step = 0

#上次触发时间
time_g = time.time()

#画面消失时间
gap_g = get_gap_g_const()

#剩余repaint次数
co_g = 0

    
#是否开启
on_g = False
on_g2 = True

#是否连续刷新
force_fresh =False

#显示在鼠标的什么方位
geoM = 1

#变换位置的信号量
to_changeG = 0

#变换位置的时间
ge_time = -3

#是否使用win32的鼠标监控，否则使用pynput
is_use_win32 = False

#当前鼠标在哪个显示器
screen_indx = 0


geogx = geogx_const
geogy = geogy_const

stop_change_geo = False

prefer_mode = -1

def set_prefer_geo():
    global prefer_mode
    if prefer_mode>0:
        prefer_mode = -1
    else:
        prefer_mode = geoM
    
def set_stop_change_geo():
    global stop_change_geo
    stop_change_geo = not stop_change_geo

    
def set_geom(mode):
    global geoM,geogx,geogy
    geoM = mode
    if mode==2:
        geoM = 2
        geogx = geochx_const
        geogy = geogy_const        
    if mode==3:
        geogx = geochx_const
        geogy = geochy_const    
    if mode==1:
        geogx = geogx_const
        geogy = geogy_const            
    if mode == 4:
        geogx = geogx_const
        geogy = geochy_const        

def from_xy_to_mode(geogx,geogy):
    if  geogx == geochx_const and         geogy == geogy_const:                
        return  2
    elif  geogx == geochx_const and         geogy == geochy_const:       
        return 3           
    elif geogx == geogx_const and         geogy == geogy_const:            
        return 1
    else:        
        return 4
    
def from_mode_to_xy(mode):
    geogx=geogy=0
    if mode==2:
        geoM = 2
        geogx = geochx_const
        geogy = geogy_const        
    if mode==3:
        geogx = geochx_const
        geogy = geochy_const    
    if mode==1:
        geogx = geogx_const
        geogy = geogy_const            
    if mode == 4:
        geogx = geogx_const
        geogy = geochy_const            
    return (geogx,geogy)    


def get_and_set_geom():
    global geoM
    if  geogx == geochx_const and         geogy == geogy_const:                
        geoM = 2
    elif  geogx == geochx_const and         geogy == geochy_const:       
        geoM=3           
    elif geogx == geogx_const and         geogy == geogy_const:            
        geoM=1
    else:        
        geoM = 4

def change_geom():
    global geogx,geogy,geoM,to_changeG,time_g,co_g,ge_time,stop_change_geo,force_change
    
    if fix_geo:
        force_change = True
    to_changeG = 1 
    co_g = 3
    time_g = time.time()
    if geoM == 1:
            set_geom(2)
    elif geoM == 2:
            set_geom(3)
            
    elif geoM == 3:
            set_geom(4)
    elif geoM == 4:
            set_geom(1)
    ge_time = time.time()
    

def off_activate():
    global on_g
    on_g = not on_g
    loger.warning('activate '+str(on_g))
    
def force():
    global force_fresh
    force_fresh = not force_fresh
    
def set_pos(a,b,c=0,d=0):    
    conf = screen_config[screen_indx]    
    m = mouse.Controller()
    global manul_mosue_time
    manul_mosue_time = time.time()
    m.position = (conf[0]+conf[2]*a//4+c, conf[1]+conf[3]*b//4+d)
    
def change_pos(i):
    global screen_indx
    screen_indx += 1
    if screen_indx>= len(screen_config):
        screen_indx =0    
    set_pos(2,2)
    set_pos(2,2)
                      
#常显
def change_gg():
    global gap_g,fix_gap
    fix_gap = not fix_gap
    if fix_gap:
        gap_g = 10000000000000
    else:
        gap_g = get_gap_g_const()
        
def change_show_c():
    global show_big_color
    show_big_color = not show_big_color

def change_show_txt():
    global show_txt
    show_txt = not show_txt
    
def change_show_draw():
    global show_draw,show_txt,show_big_color
    show_draw = not show_draw    
    show_txt = show_big_color = show_draw
    

last_screen_indx = -1
def get_screen_indx(x,y):
    for i in range(len(screen_config)):
        con = screen_config[i]
        if x>=con[0] and y>=con[1] and x<=con[0]+con[2] and y<= con[1]+con[3]:
            return i
    return 0

def do_get_geo(xx,yy):
    conf = screen_config[screen_indx]    
    if y_g<conf[1]-geogy_const:
        yy = geochy_const 
    if y_g+yxiu+geochy_const+bigger_times*pleny>conf[1]+conf[3]-check_geom_gap:
        yy = geogy_const    
    if x_g<conf[0]-geogx_const:
        xx = geochx_const
    if x_g+xxiu+geochx_const+bigger_times*plen>conf[0]+conf[2]-check_geom_gap:
        xx = geogx_const
    return xx,yy

def check_geo_inner():
    if prefer_mode<0:                
        xx = geogx
        yy = geogy
        xx,yy = do_get_geo(xx, yy)            
        return xx,yy
    a = [[1,3],[2,4]]
    if prefer_mode in a[0]:
        di = a[0]
        gao = a[1]
    else:
        di = a[1]
        gao = a[0]
    xx,yy = from_mode_to_xy(prefer_mode)
    x,y = do_get_geo(xx, yy)
    if (x,y)==(xx,yy):
        return x,y
    
    for i in gao:
        xx,yy = from_mode_to_xy(i)
        x,y = do_get_geo(xx, yy)
        if (x,y)==(xx,yy):
            return x,y       
    for i in di:
        if i!= prefer_mode:            
            return from_mode_to_xy(i)
        
def check_geom():
    global geogx,geogy
    if stop_change_geo or time.time()-ge_time<3:
        return
    xx,yy = check_geo_inner()
    geogx = xx
    geogy = yy        
    get_and_set_geom()
    return
            
remains_x = None
remains_y = None
real_pos = None
move_task = None
remains_move_sign = False

adjust_time = 0

def find_near_mod(a,m):
    n = a//m
    b = min(abs(m*n-a),abs(m*n-m-a),abs(m*n+m-a))
    if abs(m*n-a)==b:
        return m*n
    if abs(m*n-m-a)==b:
        return m*n-m
    return m*n+m    

last_random_hit_time = 0
random_hit = True

reset_remains_sign = False
def reset_remains():
    global reset_remains_sign
    reset_remains_sign = True    

move_xy = (100000,100000)

last_real_mouse_time = 0
def on_move(x,y):
    update_sta(kb_mouse_total)    
    set_has_other_when_caps()
    global move_xy,last_real_mouse_time
    global x_g,y_g,time_g,co_g,x_step,y_step,geogx,geogy
    global gap_g,screen_indx,socket_mouse_time
    global remains_x,remains_y,real_pos,move_task,remains_move_sign,force_not_show
    if time.time()-remote_gap_move_time>0.1:
        clear_remote_gap_move()
        
    set_r_other_clicks(True)
    if ctrl_pressed or alt_pressed or shift_pressed:
        clear_r_pressed(False)
    update_sta(total_g)
        
    force_not_show = False    
    if remains_move_sign:        
        remains_move_sign = False
        return    
        
    real_pos = (x,y)
    aa = mouse_force_smooth and time.time()-socket_mouse_time>1
    
    if hide_cursor_when_move and time.time()-manul_mosue_time>0.1:
        global has_fixed_mouse2
        has_fixed_mouse2 = False
    is_mouse_slow = mouse_speed_mode in (1,2,5)
    
    if slow_jump:
        is_mouse_slow = mouse_speed_mode in (2,5)
    
    inner_step_fixed = 1
    if random_hit and time.time()-manul_mosue_time >0.1 and (not aa) and \
       (not is_mouse_slow):
        global adjust_time       
        inner_step_fixed = inner_step
        if inner_step>1:
            if alt_pressed or alt_r_pressed:
                inner_step_fixed = round(inner_step_fixed*alt_gap_times)
            elif ctrl_pressed or ctrl_r_pressed:
                inner_step_fixed = round(inner_step*ctrl_gap_times)
                
        if caps_mode:
            inner_step_fixed = 1
            
        adjust_time = time.time()
        global reset_remains_sign
        
        if reset_remains_sign:
            reset_remains_sign = False
            remains_x = remains_y =None
        
        if remains_x != None:
            x += remains_x
            y += remains_y
            move_task = (remains_x,remains_y)                        
            remains_x = remains_y =None
        if round(inner_step_fixed)<=1:
            pass
        
        elif (x-x_g)**2 + (y-y_g)**2>=round(inner_step_fixed)**2:
            ll = round(math.sqrt((x-x_g)**2 + (y-y_g)**2))                                       
            nn = find_near_mod(ll,round(inner_step_fixed))
            
            while True:
                xx = round((x-x_g)/ll*nn)+x_g
                yy = round((y-y_g)/ll*nn)+y_g
                if (xx-x_g)**2 + (yy-y_g)**2>=round(inner_step_fixed)**2:
                    x = xx
                    y = yy                    
                    break
                nn += 1                                    
                print(x,y,x_g,y_g,ll,nn)
        else:
            x = x_g
            y = y_g            
            
            
        if inner_step_fixed != 1:
            global has_fixed_mouse            
            has_fixed_mouse = False
    else:
        remains_x = remains_y = None
    
    
    if time.time()-manul_mosue_time <0.1:
        update_sta(total_g_keyboard)
    else:
        last_real_mouse_time = time.time()
        if inner_step_fixed <= 1:
            update_sta(total_g_mouse_no_jump)            
        else:
            update_sta(total_g_mouse_jump)
            
        if is_sys_acc:
            update_sta(total_g_mouse_acc)
        else:
            update_sta(total_g_mouse_no_acc)            
    
    x_step = x-x_g
    y_step = y-y_g    
    x_g = x 
    y_g = y
    screen_indx = get_screen_indx(x, y)        
    global last_screen_indx
    if screen_indx!=last_screen_indx:
        last_screen_indx = screen_indx
        s = '%s#%s#%s'%tuple(screen_move_len[screen_indx])
        global remote_gap_move_x_gap,remote_gap_move_y_gap
        remote_gap_move_x_gap = screen_move_len[screen_indx][0]
        remote_gap_move_y_gap = screen_move_len[screen_indx][0]*screen_move_len[screen_indx][2]
        
        send(s)
        
    time_g = time.time()    
    if not (on_g and on_g2):
        return
            
    check_geom()
    co_g = max(1,co_g+1)            

mouse_listener = None
import os

ding_m = {}
try:
    p = '%s/../ding_default.json'%application_path
    f = open(p,encoding='utf8')
    ding_m = json.load(f)            
    f.close()
except:
    pass

class myding(QMainWindow):
    def __init__(self,x,y,w,h):
        super().__init__()        
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)
        self.setAttribute(Qt.WA_TranslucentBackground)        
        self.ori_r = QRect(x,y,w,h)
        self.setGeometry(QRect(x,y,w,h))                
        self.show()
        self.ishide = True
        t = QTimer(self)
        t.timeout.connect(self.ont)
        t.start(10)
        self.update_co = 0
        
    def ont(self):        
        if self.ishide and not self.isHidden():
            print('ding hide')
            self.hide()
            self.setGeometry(QRect(2000000,0,0,0))
        if not self.ishide and self.isHidden():
            self.show()
            self.setGeometry(self.ori_r)
        if self.update_co>0:
            self.update_co -= 1
            self.update()
        
    def do_update(self):
        self.update_co += 1        
    
    def change_show(self):
        self.ishide = not self.ishide
        self.do_update()
        
    def paintEvent(self,e):
        if self.ishide:            
            return
        
        print('myding repaint')
        painter = QPainter (self);
        opt = QStyleOption()
        opt.initFrom(self);
        self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self);
        path = QPainterPath()
        font = QFont()
        font.setBold(True);        
        font.setFamily("Arial");
        font.setPixelSize(16);            
        xy_set = set()
        for k,v in ding_m.items():
            x,y,toshow = v[0],v[1],v[2]      
            if not self.ori_r.contains(QPoint(x,y)):
                print('ding not in rec',self.ori_r,x,y)
                continue
            x-=self.ori_r.x()
            y-=self.ori_r.y()
            
            if (x,y) in xy_set:
                continue
            if  toshow==0:
                continue
            xy_set.add((x,y))
            path.addText(x, y-20, font,k)            
            pen = QPen()
            pen.setColor(Qt.white);            
            pen.setStyle(Qt.SolidLine);
            pen.setWidth(6);        
            painter.setRenderHint(QPainter.Antialiasing);    
            painter.strokePath(path, pen);        
            painter.fillPath(path, QBrush(Qt.black));  
            
            p = painter
            pen = QPen()
            pen.setWidth(3)
            pen.setColor(Qt.white)        
            p.setPen(pen)
            p.drawEllipse(QPoint(x,y),8,8)
            
            pen.setWidth(3)
            pen.setColor(Qt.black)
            p.setPen(pen)
            p.drawEllipse(QPoint(x,y),7,7)                 

mydingL = []        

win3_cmd = None
def deal_ding(ty,code):
    global ding_m
    x = code.split('#')[0].replace("'",'')
    b = code.split('#')[-1]
    if len(x)!=1 or b=='None':
        return
    print('deal_ding',ty,x)
    if ty==2:
        if x=='z':
            for i in mydingL:
                i.change_show()
            return        
        if x=='x':
            try:
                p = '%s/../ding.json'%application_path
                f = open(p,'w',encoding='utf8')
                json.dump(ding_m,f,indent=4,ensure_ascii=False)
                f.close()
            except:
                pass
            return
        
        if x=='v':
            global win3_cmd
            win3_cmd = ('deal_gear_btn','xx')            
            return
        if x=='c':
            try:                
                p = '%s/../ding.json'%application_path
                f = open(p,encoding='utf8')
                ding_m = json.load(f)            
                f.close()
            except Exception as e:
                print(e)
            for i in mydingL:
                i.do_update()            
            return            
        if x not in ding_m:
            ding_m[x] = [0,0,1,'comment']
        ding_m[x][0] = x_g
        ding_m[x][1] = y_g
        
        for i in mydingL:
            i.do_update()
        return
    
    if ty in (3,6) and x in ding_m:
        m = mouse.Controller()
        x,y = ding_m[x][0],ding_m[x][1]
        mouse.Controller().position = (x,y)
        if x == x_g and y == y_g:
            time.sleep(0.001)
            on_move(x, y)               
        if ty==3:
            time.sleep(0.1)
            m.click(mouse.Button.left,1)
    


def poll_mouse():
    import win32gui
    x=0
    y=0
    while True:
        if not is_use_win32:
            time.sleep(1)
            continue
        time.sleep(0.01)
        mouse_pos_x, mouse_pos_y = win32gui.GetCursorPos()
        if mouse_pos_x==x and mouse_pos_y==y:
            continue
        x = mouse_pos_x
        y = mouse_pos_y
        on_move(x, y)        
poll_mouse_thr = None

if os.name=='nt':      
    poll_mouse_thr = threading.Thread(target=poll_mouse)
    poll_mouse_thr.setDaemon(True)
    poll_mouse_thr.start()

def on_click(x, y, button, pressed):   
    if not pressed:
        send('3')     
        clear_r_pressed(True)    
        clear_remote_gap_move()
        clear_togg_mouse_speed()        
    set_r_other_clicks()
    update_sta(kb_mouse_total)
    if not pressed:
        return
    update_sta(key_press_counts)
    
def on_scroll(x, y, dx, dy):    
    set_r_other_clicks()
    update_sta(kb_mouse_total)
    update_sta(key_press_counts,False)
    
def set_listen():
    global is_use_win32,mouse_listener
    is_use_win32 = False
    if not mouse_listener:
        mouse_listener = mouse.Listener(on_move=on_move,on_click=on_click,    
                                        on_scroll=on_scroll)
        mouse_listener.start()        
        
def set_win32():
    global mouse_listener,is_use_win32
    is_use_win32 = not is_use_win32
    if is_use_win32:
        if mouse_listener:
            mouse_listener.stop()
            mouse_listener.join()
            mouse_listener = None
    else:
        set_listen()
        
set_listen()

def set_step_mode():    
    global step_mode
    step_mode = not step_mode

def set_gap_g(i):
    global gap_g    
    gap_g = max(0,i)                
    

hotkeys = None

def start_stop_hotkeys():
    global hotkeys
    if hotkeys ==  None:
        hotkeys = keyboard.GlobalHotKeys({                            
            '<alt>+x': change_show_draw, #是否显示放大框
            '<alt>+c': change_gg,      #是否常显
            '<alt>+z': change_fix_geo,    #放大框固定位置
            '<alt>+`': change_geom,   #手动变化放大框位置
            '<ctrl>+<alt>+r': set_stop_change_geo,    #放大框保持偏移方向   
            '<alt>+s': set_prefer_geo,        #设置放大框的偏好方向          
                        
            '<ctrl>+<alt>+/': off_activate,   #停止工作            
            '<ctrl>+<alt>+]': change_show_txt, #是否显示txt           
            '<ctrl>+<alt>+[': change_show_c,    #是否显示红绿蓝                                                                 
            '<ctrl>+<alt>+,': set_win32,          #使用win32 鼠标监听              
            '<ctrl>+<alt>+v': functools.partial(set_win4_refresh_gap_10ms,0,0,0), #鼠标刷新时间间隔                                    
            '<ctrl>+<alt>+h': set_force_not_show,
            '<ctrl>+<alt>+.': set_fix_mode, #放大框固定位置时，鼠标靠近也不会移动
            '<alt>+w': set_to_active, #激活窗口            
            
            #设置鼠标最小移动距离
            '<ctrl>+<alt>+b': functools.partial(set_inner_step,1),                                                                     
            '<ctrl>+<alt>+u': functools.partial(set_inner_step,2),                                                                     
            '<ctrl>+<alt>+i': functools.partial(set_inner_step,4),                                                                     
            '<ctrl>+<alt>+o': functools.partial(set_inner_step,6),                                                                     
            '<ctrl>+<alt>+p': functools.partial(set_inner_step,8),                                                                     
            '<ctrl>+<alt>+j': functools.partial(set_inner_step,10),                                                                     
            '<ctrl>+<alt>+k': functools.partial(set_inner_step,12),                                                                     
            '<ctrl>+<alt>+l': functools.partial(set_inner_step,14),                                                                     
            '<ctrl>+<alt>+;': functools.partial(set_inner_step,16),                                                                     
            '<ctrl>+<alt>+\'': functools.partial(set_inner_step,18),                                                                     
            
            #设置放大倍数
            '<ctrl>+<alt>+5': functools.partial(reset_config,3),
            '<ctrl>+<alt>+6': functools.partial(reset_config,4),
            '<ctrl>+<alt>+7': functools.partial(reset_config,5),
            '<ctrl>+<alt>+8': functools.partial(reset_config,6),
            '<ctrl>+<alt>+9': functools.partial(reset_config,7),
            '<ctrl>+<alt>+0': functools.partial(reset_config,8),
            
            #设置放大框消失时间
              '<ctrl>+<alt>+<f1>': functools.partial(set_gap_g,0,),
               '<ctrl>+<alt>+<f2>': functools.partial(set_gap_g,1),
               '<ctrl>+<alt>+<f3>': functools.partial(set_gap_g,2),                                                        
               '<ctrl>+<alt>+<f4>': functools.partial(set_gap_g,3),
               '<ctrl>+<alt>+<f5>': functools.partial(set_gap_g,4),
                '<ctrl>+<alt>+<f6>': functools.partial(set_gap_g,5),
                 '<ctrl>+<alt>+<f7>': functools.partial(set_gap_g,6),
                   '<ctrl>+<alt>+<f8>': functools.partial(set_gap_g,7),
                    '<ctrl>+<alt>+<f9>': functools.partial(set_gap_g,8),     
                    '<ctrl>+<alt>+<f10>': functools.partial(set_gap_g,9),     
                    '<ctrl>+<alt>+g': functools.partial(change_pos,1),            
            }) 
        hotkeys.start()
        return
    hotkeys.stop()
    hotkeys = None
start_stop_hotkeys()
add = (('0.0.0.0',listen_port))
add2 = (('0.0.0.0',listen_port2))

import json
do_gap = False

rconn1 = redis.Redis('127.0.0.1')    
rconn2 = redis.Redis('127.0.0.1')   
rconn1.delete(str(listen_port))
rconn1.delete(str(listen_port2))
rconn1.delete(str(listen_port)+'re')

sori = '`1234567890-=[];\'\\,./'
sshif = '~!@#$%^&*()_+{}:"|<>?'
assert(len(sori)==len(sshif))

shiM = {}
for i in range(len(sshif)):
    shiM[sshif[i]] = sori[i]
        
def deal_r_key(j,has_pressed,c):    
    global shift_r_pressed,alt_r_pressed,ctrl_r_pressed  
    global alt_pressed,shift_pressed,ctrl_pressed,doublem30indx
    clear_gap_move_mode()
    clear_remote_gap_move()
    reset_remains()
    doublem30indx = 0
    clear_togg_mouse_speed()
    j[2] = j[2].replace('_r','')
    if 'press' in j[0]:
        if has_pressed and (not globals()[j[2]+'_pressed']):
            set_r_other_clicks()
        else:
            set_r_sign()        
        globals()[j[2]+'_pressed'] = True                        
        print('deal_r_key',alt_pressed,shift_pressed,ctrl_pressed,shift_r_pressed,alt_r_pressed,ctrl_r_pressed)
        set_r_ms()    
        return
    
    #deal release
    def need_set():        
        if not is_r_single_clicked() :                
            return False
        return True    
    
    if need_set():        
        if not globals()[j[2]+'_r_pressed']:
            clear_r_pressed(False)
            globals()[j[2]+'_r_pressed'] = True                            
        else:
            clear_r_pressed(False)            
            
    globals()[j[2]+'_pressed'] = False
    
    if 'alt' in j[2] and not has_keyboard_clicks():
        c.press(Key.ctrl)
        c.release(Key.ctrl)        
        
    if not has_keyboard_clicks():
        global r_has_effect
        r_has_effect = True
        
    if is_r_pressed() and not is_r_single_clicked_mouse():
        clear_r_pressed(False)            
        globals()[j[2]+'_r_pressed'] = True                                    
        
    set_r_ms()

def keyboard_socket_thr():
    c = keyboard.Controller()
    while True:
        try:                            
            xx = rconn1.blpop(str(listen_port2))[1]
            ss = xx.decode()
            if socket_secret not in ss:
                continue
            ss = ss.replace(socket_secret,'')
            info_logger.warning(str(datetime.datetime.now())+' sock2 recv '+ss)
            
            print('sock2',ss)
            j = json.loads(ss)            
            
            if j[2] == "<65511>":
                j = [j[0],'key','alt']
            if j[2] == "<65056>":
                j = [j[0],'key','tab']
            if '<' in j[2] and '>' in j[2]:
                info_logger.error(str(datetime.datetime.now())+' sock2 recv error '+ss)
                
            if not keyboard_input_on:
                continue

            if 'ctrl' in j[2] or 'alt' in j[2] or 'shift' in j[2]:
                has_pressed = alt_pressed or shift_pressed or ctrl_pressed                        
                deal_r_key(j,has_pressed,c)                    
            else:
                set_r_other_clicks()
            if not v2_cap_pressed or j[0]=='release':
                if j[1]=='key':
                    getattr(c,j[0])(getattr(Key,j[2]))
                if j[1]=='keycode':
                    x = j[2]
                    if x.isupper():
                        x = x.swapcase()
                    if x in shiM:
                        x = shiM[x]
                    getattr(c,j[0])(x)                 
        except Exception as e:
            print(e)    

pause_xy_pos = None
pause_xy_conf = None
pause_x_gap = 0
pause_y_gap = 0
pause_x_gap2 = 0
pause_y_gap2 = 0
pause_xy_set = (0,0)
import math


class deal_xing():
    def __init__(self):
        self.g0 = 0
        self.big_l = 0
        self.small_l = 0
        self.times_l = 0
        self.x = 0
        self.y = 0
        self.conf = None
        self.big = 0
        self.small = 0
        self.times = 0
        self.arr = 1
        self.dx = 0
        self.dy = 0
        self.small_txt = ''
        
    def set_arr(self,a):
        x = int(a[1])
        if x == 1:
            if self.dy>0:
                self.arr = 1
            else:
                self.arr = -1
                
        if x == 2:
            if self.dy>0:
                self.arr = -1
            else:
                self.arr = 1
        if x == 3:
            if self.dx>0:
                self.arr = -1
            else:
                self.arr = 1
        if x == 4:
            if self.dx>0:
                self.arr = 1
            else:
                self.arr = -1          
        print('set_arr',x,self.dx,self.dy,self.arr)
            
    def ini2(self,a,x,y,conf,clear=True):  
        self.ini(a, x, y, conf, clear)
        self.times = 4
        return self.deal()
    def ini(self,a,x,y,conf,clear=True):        
        self.g0 = int(a[1])
        self.big_l = int(a[2])
        self.small_l = int(a[3])
        self.times_l = int(a[4])
        self.x = x
        self.y = y
        self.conf = conf         
        self.times = 10
        self.arr = 1
        if clear:
            self.big = None
            self.small = 0
                        
        return self.deal()
    
    def deal(self):
        if self.big == None:
            return self.x,self.y,self.conf
        
        one = 2*math.pi/self.big_l
        two = self.arr*one/self.small_l
        t = -1*math.pi/2+(one*self.big+two*self.small)
        self.dx = math.cos(t)*self.times*self.g0
        self.dy = math.sin(t)*self.times*self.g0
        x = self.dx+self.x
        y = self.dy+self.y
        if self.arr>=0:
            self.small_txt = str(self.small)
        else:
            self.small_txt = '-'+str(self.small)
            
        return round(x),round(y),self.conf        
    
    def input(self,a):
        if a[0]=='2':
            self.big = int(a[1])
            self.small = 0
            self.arr = 1
            
        if a[0]=='3':
            self.small = int(a[1])
            if self.big==None:
                self.big = 0
        if a[0]=='4':
            self.times = int(a[1])
        return self.deal()
    
xing_w = deal_xing()

scroll_pos = (0,0)
scroll_xy = [0,0]
scroll_back_x = 1
scroll_back_y = 1
scroll_conf = (0,0,0,0)
sc_draw = False
insert_draw_co = 0


import copy

second_mouse_remains = [0,0]
dxt1 = 0
dxt2 = 0

last_sc = ''
sc_is_same = False

def scroll_cal(ty,gx,gy,conf):
    global scroll_back_x,scroll_back_y,scroll_conf,scroll_pos,scroll_xy,sc_draw
    
    if ty == 1:
        scroll_pos = (gx,gy)
        scroll_conf = copy.deepcopy(conf)
        scroll_xy = [0,0]
        scroll_back_x = 1
        scroll_back_y = 1        
        sc_draw = False
        return
    
    if ty==2:
        conf = scroll_conf
        if gx!=0:
            scroll_xy[0] = gx*scroll_back_x
        if gy!=0:
            scroll_xy[1] = gy*scroll_back_y
            
        gx = scroll_pos[0]+scroll_xy[0]
        gy = scroll_pos[1]+scroll_xy[1]
        gx = round(gx*conf[2]+conf[0])
        gy = round(gy*conf[3]+conf[1])       
        if not sc_draw and not sc_is_same:
            sc_draw = (gx,gy)
        return gx,gy,scroll_conf
    
    if ty==3:
        scroll_back_x *= -1
        return
    if ty==4:
        scroll_back_y *= -1
        return
    
    if ty==5:
        gx = int(gx)
        gy = int(gy)
        if abs(gx)>0:
            scroll_back_x = gx
        if abs(gy)>0:
            scroll_back_y = gy


gap_move_mode = ''
gap_move_last = [0,0]
gap_move_start_pos = None
gap_move_conf = None
gap_move_last2 = [0,0]

def clear_gap_move_mode():
    global gap_move_mode
    gap_move_mode = ''

def set_gap_move_mode(s):
    global gap_move_mode,gap_move_start_pos,gap_move_conf,gap_move_last2
    if s == gap_move_mode:
        return
    if s in ('3','4') and gap_move_mode not in ('3','4'):
        print('set_gap_move_mode 3 4',gap_move_last)
        
        if gap_move_last[0]!=0 and gap_move_last[1]!=0:
            co = gap_move_last[0]*gap_move_last[1]
            if co>0:
                gap_move_last2 = [-abs(gap_move_last[0]),abs(gap_move_last[0])]
            else:
                gap_move_last2 = [-abs(gap_move_last[0]),-abs(gap_move_last[0])]
        elif gap_move_last[0]!=0:
                gap_move_last2 = [0,-abs(gap_move_last[0])]
        else:
                gap_move_last2 = [-abs(gap_move_last[1]),0]
                
        if s=='4':
            a,b = gap_move_last2
            gap_move_last2 = [-a,-b]         
        
    gap_move_mode = s
    gap_move_start_pos = (x_g,y_g)
    gap_move_conf = screen_config[screen_indx]    

def do_gap_move(a,b,mode='1'):    
    dx,dy = gap_move_last
    if mode in ('3','4'):
        dx,dy = gap_move_last2
    print('do_gap_move',mode,a,b,dx,dy)
    if not ctrl_pressed and not remote_mouse_right_pressed and not ctrl_r_pressed and (shift_pressed or shift_r_pressed):
        print('shift hit',shift_pressed or shift_r_pressed)
        if dx>0:
            dx = 1
        elif dx<0:
            dx = -1
        else:
            dx = 0
        if dy>0:
            dy = 1
        elif dy<0:
            dy= -1
        else:
            dy = 0    
    n = a
    if dx<0:
        n = b    
    x,y = gap_move_start_pos
    ax = n*dx+x
    ay = n*dy+y
    conf = gap_move_conf
    x = min(ax,conf[0]+conf[2]-4)                
    y = min(ay,conf[1]+conf[3]-4)
    x = max(conf[0]+2,x)
    y = max(conf[1]+2,y)
    
    mouse.Controller().position = (x,y)
    if x == x_g and y == y_g:
        time.sleep(0.001)
        on_move(x, y)       
        
def set_last_move(x,y):
    global gap_move_start_pos,gap_move_last,gap_move_conf
    clear_gap_move_mode()
    gap_move_last = [x,y]    

def gap_list1(a,b):
    set_gap_move_mode('1')
    do_gap_move(a, b)

def gap_list2(a,b):
    set_gap_move_mode('2')
    do_gap_move(a, b)

def gap_list3(a,b):
    set_gap_move_mode('3')
    do_gap_move(a, b,'3')
    
def gap_list4(a,b):
    set_gap_move_mode('4')
    do_gap_move(a, b,'4')
    
def deal_gap_move(n):
    global gap_move_start_pos,gap_move_conf
    set_gap_move_mode('f')
    conf = gap_move_conf
    x1,y1,x2,y2 = conf[0],conf[1],conf[0]+conf[2],conf[1]+conf[3]
    dx,dy = gap_move_last
    gap0 = max(abs(dx),abs(dy))
    x,y = gap_move_start_pos
    
    xtimes = 0
    ytimes = 0
    if dx==0:
        xtimes=10000000
    elif dx>0:
        xtimes = (x2-x)/dx
    else:
        xtimes = (x1-x)/dx
        n = 13-n
        
    if dy==0:
        ytimes=10000000
    elif dy>0:
        ytimes = (y2-y)/dy
    else:
        ytimes = (y1-y)/dy
        
    times = min(xtimes,ytimes)
        
  
    ax = (times/12*n*dx)+x
    ay = (times/12*n*dy)+y
    
    x = min(ax,conf[0]+conf[2]-gap0)                
    y = min(ay,conf[1]+conf[3]-gap0)
    x = max(conf[0]+gap0,x)
    y = max(conf[1]+4,y)
    
    mouse.Controller().position = (x,y)
    if x == x_g and y == y_g:
        time.sleep(0.001)
        on_move(x, y)             

rawk1 = ''
rawk2 = ''
pauseini = False
def set_w9():
    if show_xy_print:
        if seek_mode in (4,) and not pauseini:
            w9.is_min_ex = False
        else:
            w9.is_min_ex = True                    
            
def set_w8():
    if show_xy:
        if seek_mode==2:
            w8.set_xfirst(True)
        if seek_mode==3:
            w8.set_xfirst(False)    
        if seek_mode in (2,3) and not pauseini:
            w8.is_min_ex = False
        else:
            w8.is_min_ex = True    
gear_txt = ''
def do_gear(dx,dy,from_scroll=False):
    global gear_start_time,gear_last_move_time,gear_change_time
    gear_last_move_time = time.time()
    #print('do_gear',time.time(),dx,dy,from_scroll)
    if gear_on and mouse_speed_mode in [1,2]:
        if gmw_g.gear_mode == 0:
            gear_change_time = time.time()
            gmw_g.gear_mode = 1
            gear_cur_pos[0] = 0
            gear_cur_pos[1] = 0
            gear_start_time = time.time()    
            #print('set gear_start_time',gear_start_time,dx,dy,gear_v[0])
           
        if gmw_g.gear_mode == 1:
            #print('gear_cur_pos1',gear_cur_pos)
            gear_cur_pos[0] += dx
            gear_cur_pos[1] += dy
            #print('gear_cur_pos2',gear_cur_pos)
            if from_scroll:
                gmw_g.gear_mode = 2
                if gear_v[2]<=1.9:                    
                    gear_last_move_time = time.time()+1
            else:        
                global gear_txt
                if gear_cur_pos[0]*gear_cur_pos[0]+gear_cur_pos[1]*gear_cur_pos[1]>=gear_v[0]*gear_v[0]:                    
                    if time.time()-gear_start_time<=gear_v[1]:
                        gmw_g.gear_mode = 3                        
                    else:
                        gmw_g.gear_mode = 2
                        mouse.Controller().move(5,5)                    
                    gear_txt = '%s %s %s'%(gmw_g.gear_mode,round(math.sqrt(gear_cur_pos[0]*gear_cur_pos[0]+gear_cur_pos[1]*gear_cur_pos[1])),
                                           round((time.time()-gear_start_time)*1000)/1000)                    
                        

v2_cap_pressed = False

auto_gear = False

auto_gear_conf = {}
def set_auto_gear():
    global auto_gear,auto_gear_conf
    auto_gear = not auto_gear
    fp = '%s/../auto_gear_conf.txt'%application_path
    try:
        f = open(fp)
        auto_gear_conf = json.load(f)
        f.close()
        print(auto_gear_conf)
    except:
        pass
    
    if auto_gear:
        send('auto_gear_on')
    else:
        send('auto_gear_off')
    
on_move_q = deque()
sq_g = 0
scale_g = 0
def cal_auto_gear():
    interval = auto_gear_conf['interval']
    while len(on_move_q)>0:
        dx,dy,t = on_move_q[0]
        if time.time()-t>interval:
            on_move_q.popleft()
        else:
            break
        
    tgap = 0
    if len(on_move_q)>=2:
        dx,dy,t1 = on_move_q[0]
        dx,dy,t2 = on_move_q[-1]
        tgap = t2-t1
    dis = 0
    for i in on_move_q:
        dxs,dys,t1 = i
        dis +=  math.sqrt(dxs*dxs+dys*dys)                        
    sp = 0    
    if tgap>0:
        sp =dis/max(0.02,tgap)
    print('mosue speed',sp,dis,tgap,len(on_move_q))        
    global sq_g,scale_g
    scale_g = 1
    sq_g = int(sp)
    for i in auto_gear_conf['conf']:
        minv,maxv,v = i
        if sq_g >= minv and sq_g<maxv:
            scale_g = v
            break
    return scale_g
        

        
def deal_so(ss,source_type):
    if True:
        for i in range(1):
            global is_pressed,manul_mosue_time,remote_mouse_right_pressed       
            global pause_xy_conf,pause_xy_pos,pause_x_gap,pause_y_gap,pause_xy_set
            global pause_x_gap2,pause_y_gap2,rawk1,rawk2,v2_cap_pressed
            if socket_secret not in ss:
                continue            
            ss = ss.replace(socket_secret,'')            
            print('socket',ss,time.time())
            
            if not mouse_input_on:
                continue            
                
            global mouse_from_socket_counts,pauseini
            if 'on_move' in ss:
                dx,dy = ss.replace('on_move','').split('#')
                dx = float(dx)
                dy = float(dy)
                if auto_gear:
                    on_move_q.append((dx,dy,time.time()))
                continue
            
            update_sta(mouse_from_socket_counts,True)        
            change_in = False
            conf = screen_config[screen_indx]            
            m = mouse.Controller()                  
            if ss=='pauseini':
                pauseini = True
                continue
            if ss=='pauseover':
                pauseini = False
                set_w8()
                set_w9()
                continue
            
            if 'rawkey1' in ss:
                rawk1 = ss.replace('rawkey1','')
                continue
            if 'rawkey2' in ss:
                rawk2 = ss.replace('rawkey2','')
                continue
            if ss[:4]=='ding':
                manul_mosue_time = time.time()                            
                ty = int(ss[4])
                code = ss[5:]
                deal_ding(ty,code)
                continue
            
            def move_inner_xy(ax,ay,conf,m):
                x = min(ax,conf[0]+conf[2]-4)                
                y = min(ay,conf[1]+conf[3]-4)
                x = max(conf[0]+2,x)
                y = max(conf[1]+2,y)
                
                m.position = (x,y)
                if x == x_g and y == y_g:
                    time.sleep(0.001)
                    on_move(x, y)                     
                
            if 'xing#' in ss:  #圆 相对位移
                manul_mosue_time = time.time()       
                a = ss.replace('xing#','').split(',')
                
                if a[0]=='1':
                    ax,ay,conf2 = xing_w.ini(a,x_g,y_g,conf,True)
                elif a[0]=='5':
                    ax,ay,conf2 = xing_w.ini2(a,x_g,y_g,conf,False)
                elif a[0]=='6':
                    xing_w.set_arr(a)
                else:
                    ax,ay,conf2 = xing_w.input(a)
                move_inner_xy(ax, ay, conf2, m)                    
                continue
            
            #鼠标模式下，大距离位移
            for i in range(1,13):
                if 'gap_move%s#'%i in ss:
                    change_in = True
                    deal_gap_move(i)
            if 'gap_move_list1' in ss:
                change_in = True
                a,b = ss.replace('gap_move_list1','').split('#')
                gap_list1(int(a),int(b))
                
            if 'gap_move_list2' in ss:
                change_in = True
                a,b = ss.replace('gap_move_list2','').split('#')
                gap_list2(int(a),int(b))
                
            if 'gap_move_list3' in ss:
                change_in = True
                a,b = ss.replace('gap_move_list3','').split('#')
                gap_list3(int(a),int(b))
                
            if 'gap_move_list4' in ss:
                change_in = True
                a,b = ss.replace('gap_move_list4','').split('#')
                gap_list4(int(a),int(b))
                
            for i in range(1,13):
                if 'zyt-dy%s#'%i in ss:
                    gy = -i*(pleny-changeG)
                    mouse.Controller().move(0,gy)                       
                    change_in = True                                
                if 'zytdy%s#'%i in ss:
                    gy = i*(pleny-changeG)
                    mouse.Controller().move(0,gy)                       
                    change_in = True            
            for i in range(1,13):
                if 'zytdx%s#'%i in ss:
                    gx = i*(plen-changeGx)                    
                    mouse.Controller().move(gx,0)                       
                    change_in = True
                if 'zyt-dx%s#'%i in ss:
                    gx = -i*(plen-changeGx)                    
                    mouse.Controller().move(gx,0)                       
                    change_in = True
                    
            if change_in:
                manul_mosue_time = time.time()                            
                continue
            
            #caps_lock控制
            if ss=='caps_press':
                caps_press()
                continue
            
            if ss=='caps_release':
                caps_release()                
                continue
            
            if ss=='v2_caps_press':
                v2_cap_pressed = True
                print('v2_cap_pressed',v2_cap_pressed)
                continue
            
            if ss=='v2_caps_release':
                v2_cap_pressed = False
                print('v2_cap_pressed',v2_cap_pressed)
                continue
                                                          
            xx = ss.split('inner')            
            if len(xx)==2: #放大框内定位
                if not g_grab_pos:
                    continue
                
                manul_mosue_time = time.time()                            
                x,y = xx
                
                x = float(x)
                y = float(y)      
                
                dx = g_grab_pos[2]*x
                dy = g_grab_pos[3]*y
                x = g_grab_pos[0]+dx                
                y = g_grab_pos[1]+dy
                
                m.position = (x,y)
                if x == x_g and y == y_g:
                    time.sleep(0.001)
                    on_move(x, y)            
                continue
            
                        
            i = ss.split('#')     
            if len(i)==1: #点击              
                a = int(i[0]) 
                if not (a == 5 and not is_pressed):# and not a==4:
                    clear_r_pressed(True)                
                    clear_togg_mouse_speed()
                    clear_remote_gap_move()
                
                if a==0: #改变速度模式                   
                    change_speed_indx()                    
                     
                if a==1:
                    m.click(mouse.Button.middle,1)
                    
                if a==2:
                    m.click(mouse.Button.right,1)
                    
                if a==3:
                    m.click(mouse.Button.left,2)
                    
                if a==4:
                    is_pressed = True
                    m.press(mouse.Button.left)
                    
                if a==5:
                    if is_pressed:
                        m.release(mouse.Button.left)
                    is_pressed = False
                                    
                if a==6:                    
                    m.click(mouse.Button.left)                                                    
                    
                if a == 7: #固定鼠标速度
                    w3.fix_mouse_speed_box.click()
                    if fix_mouse_speed:
                        w3.fast_acc_b.click()                    
                    
                if a==8:                    
                    m.click(mouse.Button.middle,1)
                    
            if len(i)==2:  #全屏定位                           
                manul_mosue_time = time.time()      
               
                ax ,ay = i
                ax = float(ax)
                ay = float(ay)   
                if ax <0:
                    ax = x_g-conf[0]
                else:
                    ax = round((conf[2]*ax))
                if ay <0:
                    ay = y_g-conf[1]
                else:
                    ay = round((conf[3]*ay))
                
                move_inner_xy(ax+conf[0], ay+conf[1], conf, m)
            
            elif len(i)==3:#相对位移
                manul_mosue_time = time.time()                            
                gx,gy,a = i
                
                gx = float(gx)
                gy = float(gy)
                is_abs = 'abs' in a
                global insert_draw_co,sc_draw
                global sc_is_same,last_sc
                if a == 'sc_ini':
                    sc_draw = False    
                    last_sc = ''
                    insert_draw_co = 0
                    continue
                    
                if a == 'sc_xy':
                    re = scroll_cal(2, gx, gy, conf)                    
                    move_inner_xy(re[0], re[1], re[2], m)
                    insert_draw_co = 1
                    w10.is_min_ex = True
                    continue
                
                if a =='sc_start':
                    if i == last_sc:
                        sc_is_same = True
                    else:
                        sc_is_same = False
                    re = scroll_cal(1, gx, gy, conf)    
                    print('sc_start',conf)
                    insert_draw_co = 1                   
                    w10.is_min_ex = True
                    last_sc = i
                    continue
                
                if a =='sc_x':
                    re = scroll_cal(3, gx, gy, conf)                    
                    w10.is_min_ex = True
                    insert_draw_co = 1
                    continue
                
                if a =='sc_y':
                    re = scroll_cal(4, gx, gy, conf)                    
                    w10.is_min_ex = True
                    insert_draw_co = 1
                    continue
                if a=='sc_xy_abs':
                    re = scroll_cal(5, gx, gy, conf)                    
                    continue
                                                        
                elif a =='abs3':
                    def mv(gx,gy):
                        if gx<0:
                            x = pause_xy_pos[0]+gx-pause_x_gap+pause_x_gap2
                        else:
                            x = pause_xy_pos[0]+gx+pause_x_gap+pause_x_gap2

                        if gy<0:
                            y = pause_xy_pos[1]+gy-pause_y_gap+pause_y_gap2
                        else:
                            y = pause_xy_pos[1]+gy+pause_y_gap+pause_y_gap2

                        move_inner_xy(x, y, pause_xy_conf, m)
                        
                    gx = round(gx)
                    gy = round(gy)
                    if gx >100000:
                        pause_y_gap2 = gy
                    elif gx >10000:
                        pause_y_gap = gy                        
                    elif  gy>100000:
                        pause_x_gap2 = gx
                    elif  gy>10000:
                        pause_x_gap = gx
                    else:
                        pause_xy_set = (gx,gy)
                        
                    mv(pause_xy_set[0],pause_xy_set[1])                    
                    continue
                    
                else:  
                    set_r_other_clicks(True)                        
                    set_last_move(gx,gy)
                    if ctrl_pressed or remote_mouse_right_pressed or ctrl_r_pressed:                        
                        gx *= ctrl_speed
                        gy *= ctrl_speed
                    elif shift_pressed or shift_r_pressed:                                  
                        if gx>0:
                            gx = 1
                        elif gx<0:
                            gx = -1
                        else:
                            gx = 0
                        if gy>0:
                            gy = 1
                        elif gy<0:
                            gy= -1
                        else:
                            gy = 0
                    elif alt_pressed or alt_r_pressed:
                        gx *= alt_speed
                        gy *= alt_speed
                    
                    
                if  (abs(gx)<(plen-changeGx) and  abs(gy)<(pleny-changeG) ) or \
                    alt_pressed or shift_pressed or is_abs or alt_r_pressed or \
                    shift_r_pressed:
                    m.move(gx,gy)
                else:
                    global do_gap
                    do_gap = True
                    gx = round(gx/(plen-changeGx))*(plen-changeGx)
                    gy = round(gy/(pleny-changeG))*(pleny-changeG)
                                        
                    m.move(gx,gy)                
                
            elif len(i)==4:    #激活窗口
                global gap_g
                global to_active
                if int(i[0])==1:
                    to_active = True
                else:
                    gap_g = max(0,int(i[0]))     
                    
            elif len(i) == 6: #第二鼠标移动
                global socket_mouse_time
                global pattern_is_moving,pattern_last_move_time,pattern_start_pos,pattern_start_time,pattern_max_dis
                socket_mouse_time = time.time()
                if remote_mouse_force_smooth:
                    manul_mosue_time = time.time()                            
                
                if source_type==1 and gmw_g.gear_mode != 2:                    
                    if not pattern_is_moving:                        
                        pattern_start_pos = [x_g,y_g]
                        pattern_start_time = time.time()
                        pattern_last_move_time = time.time()
                        pattern_max_dis = 0
                        pattern_is_moving = True
                        print('pattern_is_moving',pattern_is_moving,time.time())                                                
                    else:
                        pattern_last_move_time = time.time()                                                
                        
                    
                has_float = '.' in i[0] or '.' in i[0]
                if has_float:
                    dx = float(i[0])
                    dy = float(i[1])
                else:
                    dx = int(i[0])
                    dy = int(i[1])                
                
                scale = second_mouse_scale[mouse_speed_mode-1]                                    
                if remote_mouse_right_pressed:
                    scale = second_mouse_scale[3]
                    
                if gear_on and mouse_speed_mode in [1,2] and source_type==1:                    
                    if gmw_g.gear_mode != 2:
                        scale = gear_v[3]                                
                    else:
                        scale = second_mouse_scale[0]   
                if auto_gear:
                    try:
                        cal_auto_gear()
                    except:
                        pass
                    if len(on_move_q)>1000:
                        on_move_q.clear()
                        
                    if mouse_speed_mode in [1,2] and source_type==1:                    
                        scale = scale_g
                                        
                print('second_mouse_remains1',second_mouse_remains,dx,dy)   
                global dxt1,dxt2
                dxt1+= dx
                dx = dx*scale+second_mouse_remains[0]
                dy = dy*scale+second_mouse_remains[1]                
                dx2 = dx
                dy2 = dy
                
                dx2 = int(dx)
                dy2 = int(dy)
                second_mouse_remains[0] = dx-dx2
                second_mouse_remains[1] = dy-dy2
                dxt2+= dx2
                print('second_mouse_remains2',second_mouse_remains,dx2,dy2,dxt1,dxt2)   
                
                if dx2!=0 or dy2!=0: 
                    if source_type==1:
                        remote_gap_move(dx2,dy2)
                    else:
                        m.move(dx2,dy2)  
                    if pattern_is_moving:
                        dx = x_g+dx2-pattern_start_pos[0]
                        dy = y_g+dy2-pattern_start_pos[1] 
                        dis = math.sqrt(dx*dx+dy*dy)
                        if dis>pattern_max_dis:
                            pattern_max_dis = dis                        
                            
                if source_type==1:
                    do_gear(dx2, dy2) 
                    
                if source_type==2 and has_float:
                    do_gear(dx2,dy2,True)
                
            elif len(i) == 7: #第二鼠标滚轮精确移动
                manul_mosue_time = time.time()                            
                dx = i[0]
                dy = i[1]
                dx = int(dx)
                dy = int(dy)                
                m.move(dx,dy)
                if gear_scro:
                    if gmw_g.gear_mode==0:
                        do_gear(dx, dy,True)
                    else:
                        gmw_g.gear_mode = 0
                    
            elif len(i) == 8: #第二鼠标左键
                m.click(mouse.Button.left)
            elif len(i) == 28: #第二鼠标中键
                m.click(mouse.Button.middle)
                
            elif len(i) == 9: #第二鼠标滚轮
                dx = i[0]
                dy = i[1]
                dx = int(dx)
                dy = int(dy)                                
                m.scroll(dx,dy)  
                if gear_scro:
                    if gmw_g.gear_mode==0:
                        do_gear(dx, dy,True)
                    else:
                        gmw_g.gear_mode = 0                
               
            elif len(i) == 29: #第二鼠标右键            
                if gmw_g.gear_mode==0:
                    do_gear(0, 0,True)
                else:
                    gmw_g.gear_mode = 0                
                
            elif len(i) == 10: #第二鼠标右键按住                
                remote_mouse_right_pressed = True
            elif len(i) == 11: 
                remote_mouse_right_pressed = False
                
            elif len(i) == 12: #pause lock定位开启
                pause_x_gap = pause_y_gap = 0
                pause_x_gap2 = pause_y_gap2 = 0
                pause_xy_conf = conf
                pause_xy_pos = (x_g,y_g)
                pause_xy_set = (0,0)
            
            elif len(i) == 13: #几个定位模式开启时，恢复速度
                if time.time()-change_speed_time>1:
                    clear_r_pressed(True)
                            
            elif len(i) == 14: #seek_mode 变化
                global seek_mode,time_g                
                seek_mode = int(i[0])                                                    
                   
                
                set_w8()   
                set_w9()
                    
                
                if show_xy_insert:
                    print('insert_draw_co',insert_draw_co)
                    if seek_mode in (5,) and insert_draw_co==0:
                        w10.is_min_ex = False
                    else:
                        w10.is_min_ex = True                    
                        
                print('seek_mode',seek_mode)
                time_g = time.time()
                manul_mosue_time = time.time()
            elif len(i) == 15: #改变速度
                togg_mouse_speed()
                
                        
            

                    
def key_socket_thr(n):
    while True:
        try:        
            if n==1:
                xx = rconn2.blpop(str(listen_port))[1]
            else:
                xx = rconn2.blpop(str(listen_port)+'_2')[1]
            ss = xx.decode()
            deal_so(ss,n)
        except Exception as e:
            print(e)
                   
thr_k =  threading.Thread(target=key_socket_thr,args=(1,))
thr_k.setDaemon(True)
thr_k.start()

thr_k_2 =  threading.Thread(target=key_socket_thr,args=(2,))
thr_k_2.setDaemon(True)
thr_k_2.start()

thr_k2 =  threading.Thread(target=keyboard_socket_thr)
thr_k2.setDaemon(True)
thr_k2.start()        
class my(QMainWindow):
    def __init__(self,sub):
        super().__init__()
        self.sub = sub
        sub.up = self        
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.l = QLabel('a',self)
        self.l.move(g_txt_pos[0],g_txt_pos[1])
        self.l.resize(g_txt_size[0],g_txt_size[1])
        font = self.l.font();
        font.setPointSize(screen_lable_font[screen_indx]);
        font.setBold(True);
        self.l.setFont(font);        
        self.l.setStyleSheet("QLabel { background-color : white; color : black; }");
        self.show()
        self.setGeometry(QRect(200,200,geox,geoy))        
        t = QTimer(self)
        t.timeout.connect(self.ont)
        t.start(5)
        self.hasc = False
        self.curPos = (0,0)
        self.hasfirst = False
        self.setg = False
        self.ppos =None        
        self.lshow = True
        self.ltxt = ''
        self.txttime = 0        
        self.lastGrabPos = (-1,-1)
        self.last_geo = (-1,-1,-1,-1)
        self.speed_false_co = 0
        self.last_graw_img = None
        self.fake_ij = None
        self.prefer_fix_geo = None   
        self.noPaint =  False
        self.faraway = False
        self.sub_last_geo = (100,100,200,200)
        self.self_last_geo = (100,100,200,200)
        
    def check_point_in_geo(self,x,y,g1 = None):
        if g1 == None:
            xx,yy,w,h = self.last_geo[0] ,self.last_geo[1],self.last_geo[2],self.last_geo[3]
        else:
            xx,yy,w,h = g1.x(), g1.y(),g1.width(), g1.height()
            
        if x>= xx and x<=xx+w and \
           y>= yy and y<=yy+h:
            return True
        return False
   
    def ont(self):
        global last_random_hit_time,random_hit,on_g,on_g2
        if hide_rec_when_kb:
            if not on_g:
                on_g2 = False
            else:
                if time.time() - last_real_mouse_time>gap_g:
                    on_g2 = False
                else:
                    on_g2 = True
        else:
            on_g2 = on_g
              
        if time.time()-last_random_hit_time>2:
            last_random_hit_time = time.time()
            random_hit = True
            if random_jump != 0:
                if random.randint(0,random_jump) != 0:
                    random_hit = False                
                
        if not fix_geo or force_change:
            self.prefer_fix_geo = None        
                
        global remains_x,remains_y,move_task,remains_move_sign
        if move_task:            
            mouse.Controller().move(move_task[0],move_task[1])
            move_task = None
        
        has_fixed_mouse_gap = 0.11
        if time.time()-time_g>has_fixed_mouse_gap:
            global has_fixed_mouse
            has_fixed_mouse = True
            
        if time.time()-time_g>0.9:
            reset_remains()
            
        if time.time()-time_g>0.9 or time.time()-manul_mosue_time<0.1 or \
           not hide_cursor_when_move:
            global has_fixed_mouse2
            has_fixed_mouse2 = True
            
        if time.time()-time_g>has_fixed_mouse_gap and remains_x==None and real_pos!=None:
            remains_x = real_pos[0]-x_g
            remains_y = real_pos[1]-y_g
            if remains_x!=0 or remains_y !=0:
                remains_move_sign = True
                mouse.Controller().position = (x_g,y_g)                
                           
        if to_quit:
            self.close()
            
        if not self.hasfirst:
            self.hasfirst = True          
            set_pos(2,2)
            set_pos(2,2)
            
        global co_g
        if force_fresh:
            co_g = min(1,co_g+1)
        
        aa =  time.time()- manul_mosue_time>manul_show_time and \
            (time.time()-time_g>gap_g and not self.hasc)  and not fix_gap
        bb = (time.time()-time_g<gap_g and check_grab_show_times() and \
              time.time()-last_grab_time<0.3) and  time.time()-adjust_time <1
        cc = inner_step!=1 and  time.time()-time_g<0.3 and time.time()-adjust_time <1        
        dd = time.time()-force_not_show_set_time<1
        if co_g>0 or aa or cc or \
           (fix_gap and co_g>-10) or \
           bb or dd:      
            if (on_g and on_g2):
                if self.sub.faraway:                    
                    self.sub.setGeometry(self.sub_last_geo)
                    self.sub.faraway = False
                                            
                if self.faraway:                    
                    self.setGeometry(self.self_last_geo)
                    self.faraway =False                                        
                self.repaint()
                
        if not (on_g and on_g2):        
            if not self.faraway:
                self.self_last_geo = self.geometry()
                self.setGeometry(QRect(200000,0,0,0))
                self.faraway = True
                self.repaint()
                        
            if not self.sub.faraway:
                self.sub_last_geo = self.sub.geometry()
                self.sub.setGeometry(QRect(200000,0,0,0))
                self.sub.faraway = True                
                self.sub.repaint()
                
            
            if not self.l.isHidden():
                self.l.hide()
            
    def closeEvent(self,event):
        self.sub.close()
        event.accept()
            
    
    def geo_eq(self,g1,g2):
        return g1.x()==g2.x() and g1.y()==g2.y() and g1.height()==g2.height() and g1.width()==g2.width()
    
    def do_move_win(self):
        global to_changeG,force_change
        if fix_mode:
            if  (not fix_geo) or force_change :
                force_change = False
                self.setGeometry(QRect(x_g+geogx,y_g+geogy,geox,geoy))           
                self.last_geo = (x_g+geogx,y_g+geogy,geox,geoy)
            return
                
        if force_change:
            force_change = False
            self.prefer_fix_geo = None
            self.setGeometry(QRect(x_g+geogx,y_g+geogy,geox,geoy))                        
         
            self.last_geo = (x_g+geogx,y_g+geogy,geox,geoy)          
            return                
        if not fix_geo:
            self.prefer_fix_geo = None
            self.setGeometry(QRect(x_g+geogx,y_g+geogy,geox,geoy))                        
          
            self.last_geo = (x_g+geogx,y_g+geogy,geox,geoy)          
            return                                
            
        if self.check_point_in_geo(x_g,y_g):
            if self.prefer_fix_geo==None:
                self.prefer_fix_geo = self.geometry()
            elif not  self.check_point_in_geo(x_g,y_g,self.prefer_fix_geo):
                self.setGeometry(self.prefer_fix_geo)                  
               
                g1 = self.prefer_fix_geo
                self.last_geo = (g1.x(), g1.y(),g1.width(), g1.height())            
                return
            
            self.setGeometry(QRect(x_g+geogx,y_g+geogy,geox,geoy))                        
           
            self.last_geo = (x_g+geogx,y_g+geogy,geox,geoy)

    def move_win(self):      
        global to_changeG,force_change
        to_changeG -= 1
        self.do_move_win()            
        self.sett()
        self.curPos = (x_g,y_g)        
        self.setg = True
        self.repaint()
        
    def showl(self):
        if not show_txt or (force_not_show):
            return
        self.l.show()
        
    def shownl(self):
        self.l.hide()            
    
    def paintbig(self,p,x,y,r,g,b):
        pen = QPen()          
        pen.setWidth(1);    
        pen.setColor(QColor(0,0,0))   
        p.setPen(pen);   
        for i in range(30):
            for j in range(30):                                                    
                p.drawPoint(x+i,y+j)                       
                
        pen.setColor(QColor(255,0,0))                
        p.setPen(pen);   
        
        for xx in mm[r]:
            i,j = xx
            p.drawPoint(x+i,y+j)                                         
                         
        pen.setColor(QColor(0,255,0))                
        p.setPen(pen);           
        for xx in mm[g]:
            i,j = xx
            p.drawPoint(x+i+10,y+j)                  
              
        pen.setColor(QColor(0,0,255))                
        p.setPen(pen);       
        
        for xx in mm[b]:
            i,j = xx
            p.drawPoint(x+i+20,y+j)                 

    def make_txt(self,s):        
        pp = ''        
        if is_pressed:
            pp = '⇓'
        
        if force_fresh and   is_use_win32:
            s = '!'+s
        elif force_fresh and not is_use_win32:
            s = '~'+s
        elif is_use_win32:
            s = ','+s            
        else:
            s = ' '+s
        if geogx==geogx_const and geogy == geogy_const:
            ss = '↘'+s+pp
        if geogx==geogx_const and geogy != geogy_const:
            ss = '↗'+s+pp        
        if geogx!=geogx_const and geogy != geogy_const:
            ss = '↖'+s+pp
        if geogx!=geogx_const and geogy == geogy_const:            
            ss = '↙'+s+pp
        rec = str(rec_pos)
        
        return ss+'%s'%rec
            
    def sett(self):
        if not self.ltxt:
            if not self.l.isHidden():
                self.l.hide()
            return
                
        if ((not show_txt) or force_not_show) and not self.l.isHidden():
            self.l.hide()
        if show_txt and self.l.isHidden() and (not force_not_show):            
            self.l.show()
        if not show_txt:
            return
        font = self.l.font();
        font.setPointSize(screen_lable_font[screen_indx]);
        font.setBold(True);
        self.l.setFont(font);         
        self.l.setText(self.ltxt)        
                
    def paintEvent(self,e):                        
        global co_g                                
        if not (on_g and on_g2):
            self.noPaint = True
            return                
            
        speed_not_show = not check_grab_show_times() and speed_mode and \
            time.time()-manul_mosue_time >0.1        
        
        if to_changeG>0:
            QTimer.singleShot(1,self.move_win)                    
        
        if  time.time()- manul_mosue_time>manul_show_time and \
            time.time()-time_g>gap_g and (not self.setg) and co_g<=0 and time.time()-ge_time>1:
            self.hasc = True            
            self.sub.h()
            co_g = 0   
            if  self.lshow:                
                self.lshow = False                
                QTimer.singleShot(1,self.shownl)            
            self.noPaint = True
            return
        self.noPaint = False
        self.setg = False        
        co_g -= 1        
        if co_g>5:
            co_g = 5
        
        if not self.lshow:                        
            self.lshow = True
            QTimer.singleShot(1,self.showl)
        self.hasc = False        
        
        if math.sqrt((x_g-self.curPos[0])**2+(y_g-self.curPos[1])**2)>move_thres:                    
            QTimer.singleShot(1,self.move_win)            
                        
        screen  =  QGuiApplication.primaryScreen();                
        if not self.ppos:            
            self.ppos = ((plen-1)//2,(pleny-1)//2,x_g,y_g)
        else:
            xg = x_g-self.ppos[2]
            yg = y_g-self.ppos[3]
            global do_gap
            if do_gap:
                self.ppos = [self.ppos[0],self.ppos[1],x_g,y_g]
        
            else:                
                self.ppos = [self.ppos[0]+xg,self.ppos[1]+yg,x_g,y_g]
    
    
        def set_y():
            if y_step>0:
                self.ppos[1] = changeG
            if y_step<0:
                self.ppos[1] = pleny-changeG-1
        def set_x():
            if x_step>0:
                self.ppos[0] = changeGx
            if x_step<0:
                self.ppos[0] = plen-changeGx-1
        def set_xy(i):
            if i==0:
                set_y()
            if i==1:
                set_x()               
        def move_to_lattice():
            for i in range(2):
                dd = plen-changeGx                
                gg = x_g-self.ppos[0]
                if i==1:
                    dd = pleny-changeG
                    gg = y_g-self.ppos[1]
                    
                nn = gg//dd
                mm = gg%dd
                
                if mm>nn*dd+dd/2 and gg>0:
                    self.ppos[i] = self.ppos[i] - dd +mm
                    rec_pos[i] = nn+1
                else:
                    self.ppos[i] = self.ppos[i] +mm                    
                    rec_pos[i] = nn
                                
            
        need_set_geo = False
                
        if do_gap:
            do_gap = False
            need_set_geo = True
        else:                
            for i in range(2):
                ll = plen
                chg = changeGx
                
                if i==1:
                    ll = pleny
                    chg = changeG
                        
                if self.ppos[i]<0:
                    self.ppos[i] = (ll-chg-1)                
                    set_xy(i)
                    self.ppos[2] = x_g
                    self.ppos[3] = y_g
                    need_set_geo = True
                if self.ppos[i]>=ll:
                    self.ppos[i] = chg
                    set_xy(i)
                    self.ppos[2] = x_g
                    self.ppos[3] = y_g   
                    need_set_geo = True
        if need_set_geo:                 
            move_to_lattice()            
            if step_mode:
                QTimer.singleShot(1,self.move_win)            
            
        if self.lastGrabPos == (x_g-self.ppos[0], y_g-self.ppos[1]) and not self.sub.faraway:                        
            if self.last_graw_img and speed_not_show:
                img = self.last_graw_img
            else:
                img = screen.grabWindow(0, x_g-self.ppos[0], y_g-self.ppos[1], plen+1, pleny+1).toImage();            
                self.last_graw_img = img
            
        else:            
            self.sub.stop = True
            self.sub.hasstop = False            
            self.sub.stoptime = 0
            self.sub.grabx =  x_g-self.ppos[0]
            self.sub.graby =  y_g-self.ppos[1]
            self.sub.faraway = False                        
            self.sub.setGeometry(self.sub.grabx-window2_left,self.sub.graby-window2_left,
                            window2_size,window2_size)
      
            self.sub.repaint()
            
            while not self.sub.hasstop :
                time.sleep(0.001)
                self.sub.repaint()      
              
            set_grab()            
            if self.last_graw_img and speed_not_show:
                img = self.last_graw_img
            else:                
                img = self.sub.img
                self.last_graw_img = img
            self.sub.stop = False
            self.lastGrabPos = (x_g-self.ppos[0], y_g-self.ppos[1])            
            self.sub.repaint()
        global g_grab_pos
        g_grab_pos = (x_g-self.ppos[0], y_g-self.ppos[1], plen+1, pleny+1)
        
        p = QPainter(self)           
        p.setBrush(Qt.DiagCrossPattern);        
        pen = QPen()                  
        boader_draw_info = []
        
        #画放大图
        if show_draw and not force_not_show:                                  
            for i in range(-1,plen+1):
                for j in range(-1,pleny+1):                                                                                           
                    if i==-1 or i==plen or  j==-1 or j==pleny :
                        px = bigger_times*i
                        py = bigger_times*j                                      
                        cc = img.pixelColor(max(0,i),max(0,j))
                        ii = cc.green()+cc.red()+cc.blue()                        
                        boader_color = None
                        boader_width = 0
                        boader_pos = None
                        
                        if ii>400:
                            boader_color = 0                        
                          
                        else:
                            boader_color = 1
                         
                        boader_width = bigger_times                                                                        
                        boader_pos = (px+xxiu,py+yxiu)                     
                        boader_draw_info.append((boader_color,boader_width,boader_pos))
                                                                
            img2 = img.scaled((plen+1)*bigger_times, (pleny+1)*bigger_times, Qt.KeepAspectRatio);                
            p.drawImage(xxiu-bigger_times//2,yxiu-bigger_times//2,img2)
            
        #画放大框的边框
        boader_color_sum = 0
        for boader_color,boader_width,boader_pos in boader_draw_info:            
            boader_color_sum += boader_color
            
        if boader_draw_info:
            if boader_color_sum/len(boader_draw_info)>0.5:
                pen.setColor(QColor(255,255,255))                
            else:    
                pen.setColor(QColor(0,0,0))                
                
        for boader_color,boader_width,boader_pos in boader_draw_info:                        
            pen.setWidth(boader_width);               
            p.setPen(pen)                                               
            p.drawPoint(boader_pos[0],boader_pos[1])           
        
        self.sub.repaint() 
        
        
        #this is drawing mouse pos
        if speed_not_show and self.fake_ij:
            i,j = self.fake_ij
        else:            
            i= self.ppos[0]
            j=self.ppos[1]
            self.fake_ij = (i,j)
            
        px = bigger_times*i
        py = bigger_times*j            
        cc = img.pixelColor(max(0,i),max(0,j))
        ii = cc.green()+cc.red()+cc.blue()
        cc2 = img.pixelColor(max(0,i-1),max(0,j-1))
        ss = ''
        for i in (cc2.red(),cc2.green(),cc2.blue()):
            if has_fixed_mouse:
                ss +=' '+ str(i)
            else:
                ss +=' '+ '?'*len(str(i))
        ss = ss[1:]

        
        if ii>400:
            pen.setColor(QColor(255,255,255))    
            p.setBrush(QBrush(QColor(0,0,0),Qt.Dense1Pattern))
        else:
            pen.setColor(QColor(0,0,0))                         
            p.setBrush(QBrush(QColor(255,255,255),Qt.Dense1Pattern))
    
        pen.setWidth(1);    
        p.setPen(pen);         
        if show_draw and not force_not_show:
            p.drawRect(px+xxiu-bigger_times,py+yxiu-bigger_times,3*bigger_times,3*bigger_times)            
            
        if speed_not_show:
            ss = self.ltxt
        else:            
            ss = self.make_txt(ss)                
            
        if self.ltxt != ss or force_not_show :
            self.ltxt =ss
            if force_fresh:
                if time.time()-self.txttime>0.1:
                    self.txttime = time.time()                            
                    QTimer.singleShot(1,self.sett)
            else:
                self.txttime = time.time()                            
                QTimer.singleShot(1,self.sett)
        if show_big_color and not force_not_show:
            self.paintbig(p, 0, 20, cc2.red(),cc2.green(),cc2.blue())        

class my3(QWidget):
    def __init__(self,sub):
        super().__init__()
        self.last_sq_g = 0
        self.shortk = {}
        self.last_shortk = 'A'           
        self.startt = time.time()
        self.caps = False
        self.sub = sub
        self.setui()
        self.setGeometry(QRect(200,50,450,650))
        self.show()
        t = QTimer(self)
        t.timeout.connect(self.ont)
        t.start(500)
        t2 = QTimer(self)
        t2.timeout.connect(self.ont2)
        t2.start(50)        
        self.last_txt = ''
        self.last_speed_mode = -1
             
        m = {1:'arrow_rl.cur', #black
             2:'aero_arrow_xl.cur',#white
             3:'aero_ew_xl.cur',
             4:'aero_ns_xl.cur',5:'aero_move_xl.cur',
             6:'help_rl.cur',#black+white
             7:'aero_helpsel_xl.cur',#white+white
             8:'help_l.cur',#white+black
             }
        self.iconm = {}
        for i,f in m.items():
            if not os.path.isfile('%s/%s'%(application_path,f)):
                f = '%s/../%s'%(application_path,f)
            else:
                f = '%s/%s'%(application_path,f)
                
            self.iconm[i] = QIcon(f)
    def caps_on(self):
        self.caps  = not self.caps                
        if self.caps:
            send('1')            
        else:
            send('0')   
    def arr(self):
        send('2')
    
    def get_fix_mode(self):
        mm = mouse_speed_mode
        if mm == 1 and is_sys_acc:
            mm = 6
        if mm == 2 and is_sys_acc:            
            mm = 7                            
        return mm
    
    def set_speed_icon(self):
        mm = self.get_fix_mode()                
        if self.last_speed_mode == mm:
            return
        self.last_speed_mode = mm                        
        if mm in self.iconm.keys():
            self.setWindowIcon(self.iconm[mm])
            w6.speed_icon = self.iconm[mm]
            w6.update()
            
    def clear_log(self):
        self.startt = time.time()
        global total_g,total_g_keyboard,total_g_mouse_acc,total_g_mouse_no_acc,\
               key_press_counts,kb_mouse_total,mouse_from_socket_counts,draw_counts,\
               total_g_mouse_jump,total_g_mouse_no_jump
        total_g = {'moves': 0,'time':0,'last':0}
        total_g_keyboard = {'moves': 0,'time':0,'last':0}
        total_g_mouse_no_acc = {'moves': 0,'time':0,'last':0}
        total_g_mouse_acc = {'moves': 0,'time':0,'last':0}
        key_press_counts = {'moves': 0,'time':0,'last':0}
        kb_mouse_total = {'moves': 0,'time':0,'last':0}
        total_g_mouse_jump = {'moves': 0,'time':0,'last':0}
        total_g_mouse_no_jump = {'moves': 0,'time':0,'last':0}
        mouse_from_socket_counts = {'moves': 0,'time':0,'last':0}
        draw_counts = 0
        
        
    def add_short(self,b):
        if self.last_shortk in 'abcdedfg':
            return ''
        for i in range(5):
            if self.last_shortk in ['^','_',]:
                self.last_shortk = chr(ord(self.last_shortk)+1)
                continue
            break
        
        self.shortk[self.last_shortk] = b
        r = self.last_shortk
        self.last_shortk = chr(ord(self.last_shortk)+1)
        return r
    
    def sag(self):
        self.gear_e0.setText("-1")
        self.gear_e4.setText("0")
        self.deal_gear_btn()
        self.deal_gear_btn()
        set_auto_gear()
        
    def setbtns(self,v):
        h = QHBoxLayout()
        self.speed_l = QLabel()
        h.addWidget(self.speed_l)
        
        q = QPushButton()
        x = self.add_short(q)
        q.setText('auto_gear(%s)'%x)
        q.clicked.connect(self.sag)
        h.addWidget(q)
        
        q = QPushButton()
        q.setText('clear log')
        q.clicked.connect(self.clear_log)
        h.addWidget(q)
        
        q = QPushButton('change cursor')
        s = 'change cursor'
        q.setText(s)
        q.clicked.connect(change_mouse_cursor)
        h.addWidget(q)
        
        q = QPushButton('change speed mode')
        s = 'change speed mode(%s)'%self.add_short(q)
        q.setText(s)
        q.clicked.connect(togg_mouse_speed)
        h.addWidget(q)    
        
        q = QPushButton('save config')                
        q.clicked.connect(save_config)
        h.addWidget(q)    
        
        v.addLayout(h)
    
    def settribles(self,v):
        h = QHBoxLayout()
        self.f1b = b = QCheckBox(self)        
        b.stateChanged.connect(set_force_acc_when_fast)
        h.addWidget(b)                 
        s1 = self.add_short(b)
        
        self.f2b = b = QCheckBox(self)        
        b.stateChanged.connect(set_force_acc_when_middle)
        h.addWidget(b)                 
        s2 = self.add_short(b)
        
        self.f3b = b = QCheckBox(self)
        s3 = self.add_short(b)
        b.stateChanged.connect(set_force_acc_when_all)
        h.addWidget(b)           
        
        self.fast_acc_b = b = QCheckBox(self)                
        b.stateChanged.connect(set_no_acc)        
        h.addWidget(b)               
        s4 = self.add_short(b)        
        b.setText('force_acc_when_alt_ctrl_slow_fast(%s%s%s%s)'%(s1,s2,s3,s4))        
        b.click()
        
        b = QCheckBox(self)
        b.stateChanged.connect(start_stop_hotkeys)        
        h.addWidget(b)
        ss = self.add_short(b)        
        
        b = QCheckBox(self)
        b.stateChanged.connect(toggm)        
        h.addWidget(b)
        
        b = QCheckBox(self)        
        b.setText('disable hotkey_keyboard_mouse(%s)'%ss)
        b.stateChanged.connect(toggk)
        h.addWidget(b)   
        b1 = QCheckBox(self)        
        b1.stateChanged.connect(functools.partial(set_show_anchor,0))
        b1.click()
        h.addWidget(b1)           
        
        b2 = QCheckBox(self)
        b2.stateChanged.connect(functools.partial(set_show_anchor,1))        
        b2.click()
        h.addWidget(b2)                   
        
        b = QCheckBox(self)
        b.setText('anchor(%s%s%s)'%(self.add_short(b1),self.add_short(b2),self.add_short(b)))
        b.stateChanged.connect(functools.partial(set_show_anchor,2))                
        b.click()
        h.addWidget(b)   
        
        v.addLayout(h)
    
    
    def setrec(self,v):
        h = QHBoxLayout()        
        
        b = QCheckBox(self)
        b.setText('step_mode')
        b.stateChanged.connect(set_step_mode)
        h.addWidget(b)        
        
        b = QCheckBox(self)
        b.setText('speed_mode')
        b.stateChanged.connect(set_speed_mode)
        h.addWidget(b)    
        
        
        b = QCheckBox(self)
        b.setText('force_refresh')
        b.stateChanged.connect(force)
        h.addWidget(b)      
        
        b = QCheckBox(self)
        b.setText('mouse_rec')
        b.stateChanged.connect(set_draw_mouse_rec)
        h.addWidget(b)         
        
        b = QCheckBox(self)
        b.setText('change_rec_style')
        b.stateChanged.connect(change_full_line)
        h.addWidget(b)
        
        b = QCheckBox(self)
        b.setText('off_when_kb')
        b.stateChanged.connect(set_hide_rec_kb)        
        h.addWidget(b)
        
        b = QCheckBox(self)
        b.setText('gear_scro')
        b.stateChanged.connect(set_gear_scro)        
        h.addWidget(b)

        
        v.addLayout(h)
        
    def set2(self,v):        
        h = QHBoxLayout()        
        
        b = QCheckBox(self)
        b.setText('caps_on(%s)'%self.add_short(b))
        b.stateChanged.connect(self.caps_on)
        h.addWidget(b)         
        b.click()
        
        self.toggle_draw_mouse_when_off_box = b = QCheckBox(self)
        b.setText('hide_cursor(%s)'%self.add_short(b))
        b.stateChanged.connect(change_draw_mouse_when_off)
        b.click()
        h.addWidget(b)         
        
        self.hkb = b = QCheckBox(self)
        b.setText('hide_when_move(%s)'%self.add_short(b))
        b.stateChanged.connect(set_hide_cursor_when_move)
        h.addWidget(b)
        b.click()
        
        b = QCheckBox(self)
        b.setText('seek_mode_window(%s)'%self.add_short(b))
        b.stateChanged.connect(set_show_seek_mode)
        self.show_seek_box = b
        h.addWidget(b)                
        
        self.fix_mouse_speed_box=b = QCheckBox(self)        
        b.setText('fix_speed(%s)'%self.add_short(b))
        b.stateChanged.connect(set_fix_mouse_speed)     
        b.click()
        h.addWidget(b)              
        
        b = QCheckBox(self)        
        b.setText('remote_gap(%s)'%self.add_short(b))
        b.stateChanged.connect(set_remote_gap)     
        b.click()
        h.addWidget(b)              
        
        
        v.addLayout(h)
        
        
        h = QHBoxLayout()

        b = QCheckBox(self)
        b.setText('arr(%s)'%self.add_short(b))
        b.stateChanged.connect(self.arr)
        h.addWidget(b)         
        
        b = QCheckBox(self)
        b.setText('speed_icon_off(%s)'%self.add_short(b))
        b.stateChanged.connect(set_show_speed)
        h.addWidget(b)           
        
        b = QCheckBox(self)
        b.setText('fresh_when_acc(%s)'%self.add_short(b))
        b.stateChanged.connect(set_fresh_when_acc)
        h.addWidget(b)      
        
        self.slow_noacc_b = b = QCheckBox(self)        
        b.setText('jump_when_slow(%s)'%self.add_short(b))
        b.stateChanged.connect(set_slow_jump)
        h.addWidget(b)               
        b.click()
        
        b = QCheckBox(self)        
        b.setText('fresh_when_fast(%s)'%self.add_short(b))
        b.stateChanged.connect(set_fresh_gap_on)
        b.click()
        h.addWidget(b)                       
        
        v.addLayout(h)
        
        h = QHBoxLayout()    
        
        b1 = QCheckBox(self)        
        b1.stateChanged.connect(set_show_xy2)
        b1.click()
        h.addWidget(b1)   
        
        b2 = QCheckBox(self)        
        b2.stateChanged.connect(set_show_xy3)
        b2.click()
        h.addWidget(b2)   
        
        b3 = QCheckBox(self)        
        b3.stateChanged.connect(set_show_xy_print)
        b3.click()
        h.addWidget(b3)           
        
        b4 = QCheckBox(self)        
        b4.stateChanged.connect(set_show_xy_insert)
        b4.click()
        h.addWidget(b4)           
        
        b = QCheckBox(self)
        b.setText('anchor_sign(%s%s%s%s%s)'%(self.add_short(b1),
                                         self.add_short(b2),self.add_short(b3),
                                         self.add_short(b4),self.add_short(b))   )
        b.stateChanged.connect(set_show_xy)
        h.addWidget(b)   
        b.click()
        
                                        
        b = QCheckBox(self)
        b.setText('remote_mouse_smooth')
        b.stateChanged.connect(set_remote_mouse_force_smooth)
        h.addWidget(b)         
        b = QCheckBox(self)
        b.setText('local_mouse_smooth')
        b.stateChanged.connect(set_mouse_force_smooth)
        h.addWidget(b)         
        b = QCheckBox(self)
        b.setText('up_mouse_off')
        b.stateChanged.connect(set_show_up_mouse)
        h.addWidget(b)         
        b = QCheckBox(self)
        b.setText('down_mouse_off')
        b.stateChanged.connect(set_show_down_mouse)
        h.addWidget(b)     
        v.addLayout(h)       
        
    def setui(self):        
        v = QVBoxLayout(self)
        self.setbtns(v)
        self.settribles(v)
        self.set2(v)
        self.setrec(v)
        
        h = QHBoxLayout()
        
        q = QPushButton('2nd_scale_sf⌥^⇧')                
        q.clicked.connect(self.cli_sms)
        
        h.addWidget(q)
        self.sms = []
        for i in range(5):
            e = QLineEdit(str(scale_2nd[i]))
            self.sms.append(e)        
            h.addWidget(e)        
        
        q.click()
                
        
        self.gear_btn = QPushButton('on')
        ad = self.add_short(self.gear_btn)
        self.gearLable = QLabel('pix_T_sl_sp(%s)'%ad)
        h.addWidget(self.gearLable)
        
        self.gear_btn.clicked.connect(self.deal_gear_btn)
        self.gear_e0 = QLineEdit(str(gear_v[0]))
        self.gear_e1 = QLineEdit(str(gear_v[1]))
        self.gear_e2 = QLineEdit(str(gear_v[2]))
        self.gear_e3 = QLineEdit(str(gear_v[3]))
        self.gear_e4 = QLineEdit(str(gear_v[4]))
        self.gear_btn.click()
        h.addWidget(self.gear_btn)
        h.addWidget(self.gear_e0)
        h.addWidget(self.gear_e1)
        h.addWidget(self.gear_e2)
        h.addWidget(self.gear_e3)
        h.addWidget(self.gear_e4)
        self.gear_btn.click()
        v.addLayout(h)     
        
        h = QHBoxLayout()
        
        q = QPushButton('pattern')                
        s = self.add_short(q)
        q.setText('pattern(%s)'%s)
        q.clicked.connect(self.cli_pattern)        
        h.addWidget(q)
        self.pattern_e = []
        for i in range(len(pattern_v)):
            e = QLineEdit(str(pattern_v[i]))
            self.pattern_e.append(e)        
            h.addWidget(e)        
        q.click()
        q.click()
            
        self.e1 = QLineEdit('-1')
        q = QPushButton('pixels_per_move')
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)
        q.clicked.connect(self.move_cli)
        q.click()
        h.addWidget(q)
        h.addWidget(self.e1)
        
        
        self.e2 = QLineEdit(str(gap_g_const))
        q = QPushButton('disappear time')      
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)        
        q.clicked.connect(self.move_cli2)
        h.addWidget(q)
        h.addWidget(self.e2)        
        v.addLayout(h)     
        
        h = QHBoxLayout()
        self.e3 = QLineEdit(str(win4_refresh_gap_10ms))
        self.e32 = QLineEdit(str(speed_thres))
        self.e33 = QLineEdit(str(speed_thres_min))
        q = QPushButton('refresh_10ms speed gap')   
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)        
        q.clicked.connect(self.move_cli3)
        h.addWidget(q)
        h.addWidget(self.e3)
        h.addWidget(self.e32)
        h.addWidget(self.e33)
        
        self.e4 = QLineEdit()
        q = QPushButton('random_jump')        
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)        
        q.clicked.connect(self.move_cli4)
        h.addWidget(q)
        h.addWidget(self.e4)        
        v.addLayout(h)             
        
        h = QHBoxLayout()
        self.e5 = QLineEdit(str(mouse_slow_speed))
        self.e6 = QLineEdit(str(mouse_fast_speed))
        self.e7 = QLineEdit(str(mouse_fast_speed_no_acc))
        q = QPushButton('slow fast no_acc_fast') 
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)        
        q.clicked.connect(self.move_cli5)
        h.addWidget(q)
        h.addWidget(self.e5)
        h.addWidget(self.e6)                
        h.addWidget(self.e7)             
        
        
        self.e_rec1 = QLineEdit('100')
        self.e_rec2 = QLineEdit('80')        
        q = QPushButton('rec_w_h')         
        q.clicked.connect(self.move_cli_rec)
        h.addWidget(q)
        h.addWidget(self.e_rec1)
        h.addWidget(self.e_rec2)
        
        v.addLayout(h)             
        
        h = QHBoxLayout()
        self.e71 = QLineEdit(str(alt_r_ms))
        self.e72 = QLineEdit(str(ctrl_r_ms))
        self.e73 = QLineEdit(str(shift_r_ms))
        q = QPushButton('alt_ctrl_shift_speed')        
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)        
        q.clicked.connect(self.move_cli7)
        h.addWidget(q)
        h.addWidget(self.e71)
        h.addWidget(self.e72)                
        h.addWidget(self.e73)                
       
        
        self.e81 = QLineEdit(str(alt_gap_times))
        self.e82 = QLineEdit(str(ctrl_gap_times))
        
        q = QPushButton('alt_ctrl_jump_bigger')        
        s = '%s(%s)'%(q.text(),self.add_short(q))
        q.setText(s)        
        q.clicked.connect(self.move_cli8)
        h.addWidget(q)
        h.addWidget(self.e81)
        h.addWidget(self.e82)                        
        v.addLayout(h)                     
        
        self.tx = QTextEdit()
        self.tx.setReadOnly(True)
        v.addWidget(self.tx)
        
        self.setLayout(v)

    def keyPressEvent(self,e):    
        QModifiers = QApplication.keyboardModifiers()                
        x = int(QModifiers) & Qt.AltModifier
        if x!=0:
            return
        
        x = e.key()
        if type(x) != type(int(1)):
            return
        if x<65 or x>100:
            return
            
        if chr(e.key()) in self.shortk:
            b = self.shortk[chr(e.key())]
            b.click()
        return
       
    def get_txt(self):
        ss = 'remote_gap 需要把remote_gap_scale.json 置于上级目录。5个值，依次是alt、ctrl、shift、快速模式、慢速模式下的倍率。\n'
        ss += 'pix_T 说明：距离阈值，时间阈值，慢速模式失效时间，快速模式速度，快速模式失效时间。慢速模式使用的是2nd_scale的第一个速度。\n'
        ss += 'pattern 说明：是否开启，是否在托盘提示，认为停止移动的时间间隔，进入慢速模式的最大时间阈值、最大距离阈值、最小距离阈值\n'
        ss += '%s ## %s ## conf_ok:%s  anchor: xing scroll insert 中间圆点\n'%(pattern_txt,gear_txt,ini_config_ok)
        ss += 'anchor_sign: insert、scroll 右下圆点，print、insert、pause坐标\n'
        ss += " '<alt>+x': #是否显示放大框,同时修改txt rbg显示 %s  ####  "%(show_draw)
        ss += "'<alt>+c':  #是否常显 %s\n"%fix_gap
        ss += "'<alt>+z':  #放大框固定位置 %s  ##### "%fix_geo        
        ss += "'<alt>+s': #设置放大框的偏好方向 %s\n"%prefer_mode
        
        ss += "'<ctrl>+<alt>+/':    #停止工作 %s ### "% (not on_g)
        ss += "'<ctrl>+<alt>+r': #放大框保持偏移方向  %s ### "%stop_change_geo        
        ss += "'<ctrl>+<alt>+]':  #是否显示txt %s\n"%show_txt
        ss += "'<ctrl>+<alt>+[': #是否显示红绿蓝 %s ### "%show_big_color        
        ss += "'<ctrl>+<alt>+,': #使用win32 鼠标监听 %s\n"%is_use_win32        
        ss += "'<ctrl>+<alt>+.': #放大框固定位置时，鼠标靠近也不会移动 %s\n"%fix_mode                
        
        ss +='当前鼠标加速：%s\n'%is_sys_acc  
        ss += "toggle_force_refresh: #强制刷新 %s\n"%force_fresh
        ss += "set_step_mode: #放大框和鼠标框同步移动 %s\n"%step_mode
        ss += "set_speed_mode: #限制放大框刷新频率 %s\n"%speed_mode        
        ss += "change_full_line:  #改变鼠标框样式 %s\n"%mouse_rec_full_line
        
        ss += 'win1 geo %s\n'%self.sub.geometry()
        ss += 'win2 geo %s\n'%self.sub.sub.geometry()
        ss += 'per move %s   disappear time %s gap times %s %s\n'%(inner_step,gap_g,alt_gap_times,ctrl_gap_times)
        
        ss += 'win4_refresh_gap_10ms %s %s %s  random_jump %s\n'%\
            (win4_refresh_gap_10ms,speed_thres,speed_thres_min,random_jump)
        ss += 'mouse speed:slow,acc,no_acc,alt,ctrl,shift,current %s %s %s, %s %s %s,%s\n'\
            %(mouse_slow_speed,mouse_fast_speed,mouse_fast_speed_no_acc,
              alt_r_ms,ctrl_r_ms,shift_r_ms,mouse_current_speed)                
        
        ss += get_sta()
        
        return ss
    
    def ont2(self):
        global win3_cmd
        if self.last_sq_g!=sq_g:
            self.last_sq_g=sq_g
            self.speed_l.setText(str(sq_g)+" "+str(scale_g))
            
        if win3_cmd!=None:
            a,b = win3_cmd
            win3_cmd = None
            if a=='deal_gear_btn':
                self.deal_gear_btn()        
        if show_speed_icon:
            self.set_speed_icon()
    def ont(self):                
        ss = self.get_txt()
        if ss!=self.last_txt:
            self.last_txt = ss
            st = int(time.time()-self.startt)
            self.tx.setText(ss+' | running %ss'%st)            
        
    def cli_sms(self):
        for i in range(5):
            s = self.sms[i].text()  
            try:
                global second_mouse_scale
                second_mouse_scale[i] = float(s)            
            except:
                pass
            
    def move_cli(self):
        s = self.e1.text()  
        try:
            set_inner_step(int(s),True)
        except:
            print('move_cli failed')
            
    def move_cli2(self):
        s = self.e2.text()  
        try:
            set_gap_g(float(s))
        except:
            print('move_cli2 failed')
            
            
    
    def move_cli_rec(self):
        s1 = self.e_rec1.text()  
        s2 = self.e_rec2.text()  
        
        try:
            global rec_w,rec_h
            rec_w = int(s1)
            rec_h = int(s2)            
        except:
            print('move_cli_rec failed')
    
    def move_cli5(self):
        s1 = self.e5.text()  
        s2 = self.e6.text()  
        s3 = self.e7.text()  
        try:
            global mouse_slow_speed,mouse_fast_speed,mouse_fast_speed_no_acc
            mouse_slow_speed = int(s1)
            mouse_fast_speed = int(s2)
            mouse_fast_speed_no_acc = int(s3)            
        except:
            print('move_cli5 failed')

    def move_cli7(self):
        s1 = self.e71.text()  
        s2 = self.e72.text()  
        s3 = self.e73.text()  
        try:
            global alt_r_ms,ctrl_r_ms,shift_r_ms
            alt_r_ms = int(s1)
            ctrl_r_ms = int(s2)
            shift_r_ms = int(s3)
        except:
            print('move_cli7 failed')
    
    def move_cli8(self):
        s1 = self.e81.text()  
        s2 = self.e82.text()          
        try:
            global alt_gap_times,ctrl_gap_times
            alt_gap_times = float(s1)
            ctrl_gap_times = float(s2)            
        except:
            print('move_cli8 failed')
            
                
    def move_cli3(self):
        s = self.e3.text()  
        s2 = self.e32.text()  
        s3 = self.e33.text()  
        try:
            set_win4_refresh_gap_10ms(int(s),int(s2),int(s3))
        except:
            print('move_cli3 failed')            
            
    def move_cli4(self):
        s = self.e4.text()  
        try:
            set_random_jump(int(s))
        except:
            print('move_cli4 failed')            
            
    def cli_pattern(self):
        for i in range(len(pattern_v)):
            s = self.pattern_e[i].text()  
            try:                
                pattern_v[i] = float(s)            
                if i==0:                    
                    if float(s)>0:
                        self.gear_e0.setText("-1")
                        self.gear_e4.setText("0")
                        self.deal_gear_btn()
                        self.deal_gear_btn()
                    self.pattern_e[i].setText(str(-1*float(s)))
            except:
                pass

            
    def deal_gear_btn(self):
        global gear_on
        gear_on = not gear_on
        if gear_on:
            self.gear_btn.setText('off')
        else:
            self.gear_btn.setText('on')
            
        s0 = self.gear_e0.text()
        s1 = self.gear_e1.text()
        s2 = self.gear_e2.text()
        s3 = self.gear_e3.text()
        s4 = self.gear_e4.text()
        try:
            gear_v[0] = float(s0)
            gear_v[1] = float(s1)
            gear_v[2] = float(s2)
            gear_v[3] = float(s3)
            gear_v[4] = float(s4)
        except:
            pass
        
    def closeEvent(self,event):
        self.sub.close()
        w6.close()
        event.accept()    
            
class my2(QMainWindow):
    def __init__(self):
        super().__init__()    
        self.up = None
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setStyleSheet("background-color:black;")                    
        self.setGeometry(QRect(200,200,200,200))       
        self.show()
        self.grabx = self.graby = self.grabw = self.grabh = 0
        self.drawL = []
        self.stop = False
        self.hasstop = False
        self.img = None
        self.stoptime = 0
        self.toClear = False
        self.last_geo = (0,0,0,0)
        self.pixmap_g = None
        self.faraway = False

        
    def h(self):
        self.toClear = True
        self.repaint()        
            
    def paintEvent(self,e):               
        if not (on_g and on_g2):             
            return
        
        if self.toClear:            
            self.toClear = False
            return        
        
        if self.stop:
            self.stoptime += 1            
            if self.stoptime==2:                                
                screen  =  QGuiApplication.primaryScreen()        
                self.img = screen.grabWindow(0, self.grabx, self.graby, plen+1, pleny+1).toImage();            
                self.hasstop = True            
                
        rx = window2_left
        ry = window2_left
        p = QPainter(self) 
        pen = QPen()          
        if force_not_show :
            return
                       
        if not draw_mouse_rec:
            return
        
        def draw_corner(x,y,w,h,wl,wly):
            p.drawLine(x,y,x+wl,y)
            p.drawLine(x,y,x,y+wly)
            
            p.drawLine(x,y+h,x,y+h-wly)
            p.drawLine(x,y+h,x+wl,y+h)
            
            p.drawLine(x+w,y+h,x+w-wl,y+h)
            p.drawLine(x+w,y+h,x+w,y+h-wly)
            
            p.drawLine(x+w,y,x+w,y+wly)
            p.drawLine(x+w,y,x+w-wl,y)
            
        pen.setColor(QColor(0,0,0))                    
        pen.setWidth(gg_size)
        p.setPen(pen)
        if gg_size%2==0:
            x,y,w,h = rx-(gg_size+2),ry-(gg_size+2),plen+(gg_size+1)*2+1,pleny+(gg_size+1)*2+1
        else:
            x,y,w,h = rx-(gg_size+1),ry-(gg_size+1),plen+(gg_size+1)*2,pleny+(gg_size+1)*2
            
        q = QRegion(x,y,w+1,h+1)
        q2 = QRegion(x+gg_size,y+gg_size,w-2*gg_size,h-2*gg_size)
        self.setMask(q.subtracted(q2))
        
        if not mouse_rec_full_line:
            draw_corner(rx-gg_size,ry-gg_size,plen+2*gg_size,pleny+2*gg_size,12,8)
        else:
            p.drawRect(rx-gg_size,ry-gg_size,plen+2*gg_size,pleny+2*gg_size)         
        
        pen.setColor(QColor(255,255,255))                    
        pen.setWidth(1)
        p.setPen(pen)
        
        if not mouse_rec_full_line:
            draw_corner(x,y,w,h,13,9)                    
        else:
            p.drawRect(x,y,w,h)                    
      
    def closeEvent(self,event):
        self.up.close()
        event.accept()    

def on_press(key):    
    update_sta(kb_mouse_total)
    update_sta(key_press_counts)
   
listener = keyboard.Listener(
    on_press=on_press
)   
listener.start()

class my4(QMainWindow):
    def __init__(self,draw_pos,sub=None):
        super().__init__()  
        self.draw_pos = draw_pos
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)                
        self.setStyleSheet("background-color:black;")                    
        self.show()
        self.setGeometry(QRect(200,200,0,0))        
        self.speed_q = deque()
        
        if draw_pos == 1:                                 
            self.last_moves_count = 0       
            self.sub = sub            
            t = QTimer(self)
            t.timeout.connect(self.ont)
            t.start(5)        
            self.last_pos = None
            self.last_time = time.time()    
            self.faraway = False
            self.last_draw_time = 0
            self.last_has_fixed = None            
            
    def move_win(self,x,y):        
        if self.draw_pos == 1:                        
            self.setGeometry(x+mouse_cursor_pos1[0],y+mouse_cursor_pos1[1],
                             mouse_cursor_size,mouse_cursor_size)
        else:
            self.setGeometry(x+mouse_cursor_pos2[0],y+mouse_cursor_pos2[1],
                             mouse_cursor_size2,mouse_cursor_size2)                
    def set_faraway(self):
        self.setGeometry(QRect(200000,0,0,0))
        
    def do_log(self):
        if self.last_moves_count == total_g['moves']:
            return
        if time.time()-time_g<1:
            return
        self.last_moves_count = total_g['moves']
        do_loger()
    
    def max_speed(self):                
        self.speed_q.append((x_g,y_g,time.time()))
        while True:
            if len(self.speed_q)==1:
                break
            if self.speed_q[0][2]>=time.time()-0.1 and \
               (self.speed_q[0][0],self.speed_q[0][1]) !=(x_g,y_g):
                break
            self.speed_q.popleft()
        max_sp = 0        
        for i in self.speed_q:
            x,y,t = i
            mouse_len = math.sqrt( (x_g-x)**2+(y_g-y)**2 )
            tt = self.speed_q[-1][2]-t+0.00001
            timegap = max(0.05,tt)                        
            msp = mouse_len/timegap
            if msp>max_sp:
                max_sp = msp
                
        return max_sp
        
    def ont(self):        
        self.do_log()
        
        global to_active
        if to_active:
            self.activateWindow()
            to_active = False
            
        if force_not_show or (on_g and on_g2) or not draw_mouse_when_off:
            if  self.faraway:
                return
            self.set_faraway()
            self.sub.set_faraway()
            self.faraway = True            
            return         
        
        
        if self.last_pos == (x_g,y_g) and \
           time.time()-time_g>gap_g+0.01*win4_refresh_gap_10ms and \
           time.time()-manul_mosue_time>3:
            if not self.faraway:                
                self.set_faraway()
                self.sub.set_faraway()
                self.faraway = True
            return
        if self.last_pos == (x_g,y_g) and self.last_has_fixed==has_fixed_mouse2 and \
               not self.faraway:            
            return        
        
        if mouse_cursor_pixmap == None:
            change_mouse_cursor()                    
        
        if self.last_pos==None:
            self.last_pos = (x_g,y_g)                       
                            
        acc_can_skip = not mode2_and_acc_sign
        if fresh_gap_on:
            acc_can_skip = True
        
        if time.time()-self.last_draw_time<0.01*win4_refresh_gap_10ms and \
           self.max_speed()>speed_thres \
            and acc_can_skip and not acc_no_fresh_sign and \
           time.time()-manul_mosue_time>0.1 and (not caps_mode) and \
           (self.last_pos[0]-x_g)**2+(self.last_pos[1]-y_g)**2 < speed_thres_min**2:                        
            return        
        
        self.faraway = False                 
        x,y = x_g,y_g
        
        if show_up_mouse:
            self.move_win(x,y)
        else:
            self.set_faraway()
            
        if show_down_mouse:
            self.sub.move_win(x,y)
        else:
            self.sub.set_faraway()            
    
        if self.last_pos!=(x,y):
            global draw_counts
            draw_counts += 1
        
        self.last_pos = (x,y)    
        self.last_has_fixed = has_fixed_mouse2
        
        if show_up_mouse:            
            if self.last_has_fixed:                
                re = QRegion(0 , 0, 9,9, QRegion.Ellipse);
                self.setMask(re)     
            self.update()            
                
        if show_down_mouse:                  
            self.sub.update()
            
        self.last_draw_time = time.time()        
  
    def paintEvent(self,e):                 
        p = QPainter(self) 
        if self.draw_pos==2:            
            ma = mouse_cursor_pixmap2.mask()                   
            self.setMask(ma)                             
            p.setRenderHint(QPainter.Antialiasing);        
            p.drawPixmap(0,0,mouse_cursor_size2,mouse_cursor_size2,mouse_cursor_pixmap2)
            return      
        
        if (not has_fixed_mouse2):                                    
            re = QRegion(100 , 100,101 ,101, QRegion.Ellipse);
            self.setMask(re)                           
            return
        
        re = QRegion(0 , 0, 9,9, QRegion.Ellipse);
        self.setMask(re)                 
        pen = QPen()
        qb = QBrush()
        qb.setColor(Qt.white)
        qb.setStyle(Qt.SolidPattern)        
        pen.setColor(Qt.white)
        pen.setWidth(1)    
        p.setPen(pen)
        p.setBrush(qb)           
        p.drawEllipse(QPoint(4,4),2,2)        

class my42(QMainWindow):
    def __init__(self,draw_pos,sub=None):
        super().__init__()  
        self.draw_pos = draw_pos
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)                
        self.setStyleSheet("background-color:black;")                    
        self.show()
        self.setGeometry(QRect(200,200,0,0))                
        t = QTimer(self)
        t.timeout.connect(self.ont)
        t.start(5)        
        self.last_pos = None
        self.last_time = time.time()    
        self.faraway = False
        self.last_draw_time = 0
        self.last_has_fixed = None            
        
    def move_win(self,x,y):                
        self.setGeometry(x+self.draw_pos[0]*rec_w,y+self.draw_pos[1]*rec_h,
                             mouse_cursor_size,mouse_cursor_size)
        
    def set_faraway(self):
        self.setGeometry(QRect(200000,0,0,0))
                
    def ont(self):                                            
        if time.time() - last_real_mouse_time>gap_g or rec_h==0 or rec_w==0:        
            if  self.faraway:
                return
            self.set_faraway()            
            self.faraway = True            
            return         
        
        
        if self.last_pos == (x_g,y_g) :
            return
                
        if mouse_cursor_pixmap == None:
            change_mouse_cursor()                    
        
        if self.last_pos==None:
            self.last_pos = (x_g,y_g)                       
        self.faraway = False                 
        x,y = x_g,y_g
                
        self.move_win(x,y)                    
        self.last_pos = (x,y)            
        self.update()            
  
    def paintEvent(self,e):                 
        p = QPainter(self)     
        pi = None
        if self.draw_pos[1]<0 and self.draw_pos[0]<0:
            pi = mouse_cursor_rec
        if self.draw_pos[1]<0 and self.draw_pos[0]>0:
            pi = mouse_cursor_rec2
        
        if self.draw_pos[1]>0 and self.draw_pos[0]<0:
            pi = mouse_cursor_rec4
        
        if self.draw_pos[1]>0 and self.draw_pos[0]>0:
            pi = mouse_cursor_rec3
            
        ma = pi.mask()                   
        self.setMask(ma)                             
        p.setRenderHint(QPainter.Antialiasing);        
        p.drawPixmap(0,0,32,32,pi)


class my5(QMainWindow):
    def __init__(self):
        super().__init__()        
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint)
        self.setGeometry(QRect(200,200,40,40))        
        self.speed_icon = None
        self.last_sm = -1
        self.show()
        self.last_s = True
        self.tray = QSystemTrayIcon(self)
        self.tray.activated.connect(self.trayA)
        self.tray.setToolTip('mfli2')
             
              
        m = {
            1:'aero_arrow_xl.cur',
             2:'aero_ns_xl.cur',#精确定位
             3:'aero_ns_xl.cur',#精确定位2
             5:'aero_link_l.cur',#大致定位
             4:'aero_pin_l.cur',#绝对定位
             6:'aero_move_xl.cur',#相对位移
             7:'move_l.cur',             #xing
             8:'arrow_rl.cur',             
             9:'no_l.cur',           
             10:'aero_unavail_xl.cur',
             11:'aero_pen_l.cur', #左键盘控制方向
             12:'pen_rl.cur',
             13:'busy_l.cur',#gear慢速模式
             14:'aero_unavail_xl.cur',#gear快速模式
             15:'up_l.cur',#gear选择模式
            }
        
        self.iconm = {}
        for i,f in m.items():
            if not os.path.isfile('%s/%s'%(application_path,f)):
                f = '%s/../%s'%(application_path,f)
            else:
                f = '%s/%s'%(application_path,f)
            self.iconm[i] = QIcon(f) 
            if i==2:
                icon_g = QIcon(f)    
                mouse_cursor_rec0 = icon_g.pixmap(icon_g.actualSize(QSize(32, 32)))            
                rm = QTransform()
                rm.rotate(90);
                self.iconm[i] = QIcon(mouse_cursor_rec0.transformed(rm))
            if i==15:
                icon_g = QIcon(f)    
                mouse_cursor_rec0 = icon_g.pixmap(icon_g.actualSize(QSize(32, 32)))            
                rm = QTransform()
                rm.rotate(180);
                self.iconm[i] = QIcon(mouse_cursor_rec0.transformed(rm))
                
        
        self.ont()
        self.tray.show()  
        t2 = QTimer(self)
        t2.timeout.connect(self.ont)
        t2.start(10)                
    def mouseMoveEvent(self,e):
        self.showMinimized()
        return
      
    def paintEvent(self,e):       
        p = QPainter(self)
        pix = self.speed_icon.pixmap(self.speed_icon.actualSize(QSize(32, 32)))
        
        p.drawPixmap(0,0,32,32,pix)
        
    
    def trayA(self,a):        
        if a == self.tray.MiddleClick:
            sys.exit(0)
            
    def closeEvent(self,event):        
        w3.close()
        event.accept()          
        
    def deal_gear(self):        
        global gear_last_move_time
        global pattern_is_moving,pattern_last_move_time,pattern_start_pos,pattern_start_time
        if gmw_g.gear_mode!=2:
            if time.time()-pattern_last_move_time>pattern_v[2] and pattern_is_moving:
                pattern_is_moving = False
                print('pattern_is_moving',pattern_is_moving,time.time())
                
                dx = x_g-pattern_start_pos[0]
                dy = y_g-pattern_start_pos[1] 
                dis = math.sqrt(dx*dx+dy*dy)
                tgap =  pattern_last_move_time-pattern_start_time
                global pattern_txt
                pattern_txt = 'pattern %s %s %s'%(round(dis),round(pattern_max_dis),round(tgap*1000)/1000)
                print('pattern',dis,tgap,time.time())
                if gear_on and pattern_v[0]>0 and tgap<pattern_v[3] and dis<pattern_v[4] and pattern_max_dis<pattern_v[4] and dis>pattern_v[5]:
                    dstx = (pattern_start_pos[0]+x_g)//2
                    dsty = (pattern_start_pos[1]+y_g)//2
                    if not auto_gear:
                        mouse.Controller().position = (dstx,dsty)
                    gmw_g.gear_mode = 2
        
        if gmw_g.gear_mode==1:
            if time.time()-gear_change_time>gear_v[1]-0.01:
                global gear_txt
                gmw_g.gear_mode = 2
                gear_txt = '%s %s %s'%(gmw_g.gear_mode,round(math.sqrt(gear_cur_pos[0]*gear_cur_pos[0]+gear_cur_pos[1]*gear_cur_pos[1])),
                                       round((time.time()-gear_start_time)*1000)/1000)                
                if gear_v[2]<=1.9:                    
                    gear_last_move_time = time.time()+1
            return
        gg = gear_v[2]
        if gmw_g.gear_mode==3 :
            gg = gear_v[4]
        if time.time()-gear_last_move_time>gg:                        
            gmw_g.gear_mode = 0            
            
    def ont(self):  
        self.deal_gear()
        if self.last_s != show_seek_mode:
            self.last_s = show_seek_mode
            if not self.last_s:
                self.hide()
            else:
                self.show()
        seek_mode2 = seek_mode
        if seek_mode2==11 and is_pressed:
            seek_mode2 = 12
        if seek_mode2==1 and caps_mode:
            seek_mode2 = 10            
        if seek_mode2==1 and is_pressed:
            seek_mode2 = 8
        if seek_mode2==1 and fix_mouse_speed:
            seek_mode2 = 9
        if gear_on:
            #if gmw_g.gear_mode == 1:
                #seek_mode2 = 15 
            if gmw_g.gear_mode == 2 and not auto_gear:
                seek_mode2 = 13
            if gmw_g.gear_mode == 3 and gear_v[4]>0.19:
                seek_mode2 = 14
        if pattern_v[0]>0 and pattern_v[1]>0 and gmw_g.gear_mode !=2:
            if pattern_is_moving:
                seek_mode2 = 14
                
        if self.last_sm == seek_mode2:
            return
        
        self.last_sm = seek_mode2        
        if self.last_sm in self.iconm.keys():
            self.setWindowIcon(self.iconm[self.last_sm])            
            self.tray.setIcon(self.iconm[self.last_sm])
        
        
class my6(QMainWindow):
    def __init__(self):
        super().__init__()        
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)
        self.setAttribute(Qt.WA_TranslucentBackground)        
        self.setGeometry(QRect(200,200,100,100))        
        t2 = QTimer(self)
        t2.timeout.connect(self.ont)
        t2.start(10)                
        self.show()
              
    def paintEvent(self,e):
        print('my6 paint')
        p = QPainter(self)
        pen = QPen()
        pen.setWidth(3)
        pen.setColor(Qt.white)        
        p.setPen(pen)
        p.drawEllipse(QPoint(20,20),8,8)
        
        pen.setWidth(3)
        pen.setColor(Qt.black)
        p.setPen(pen)
        p.drawEllipse(QPoint(20,20),7,7)                
        
    def ont(self):                
        if seek_mode == 7 and show_anchor[0] :            
            self.setGeometry(xing_w.x-20,xing_w.y-20,100,100)
            if self.isHidden():
                self.show()
            return
        if seek_mode == 6 and show_anchor[1]:            
            self.setGeometry(pause_xy_pos[0]-20,pause_xy_pos[1]-20,100,100)
            if self.isHidden():
                self.show()
            return     
        if seek_mode == 5 and sc_draw and show_anchor[2]:                      
            self.setGeometry(sc_draw[0]-20,
                             sc_draw[1]-20,100,100)
            if self.isHidden():
                self.show()
            return             
        if not self.isHidden():
            self.hide()        


class my66(QMainWindow):
    def __init__(self):
        super().__init__()        
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)
        self.setAttribute(Qt.WA_TranslucentBackground)        
        self.setGeometry(QRect(200,200,100,100))        
        t2 = QTimer(self)
        t2.timeout.connect(self.ont)
        t2.start(10)                
        self.show()
        self.r1 = ''
        self.r2 = ''
        self.r3 = ''
        self.r4 = ''
              
    def paintEvent(self,e):
        print('my66 repaint')
        painter = QPainter (self);
        opt = QStyleOption()
        opt.initFrom(self);
        self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self);
        path = QPainterPath()
        font = QFont()
        font.setBold(True);        
        font.setFamily("Arial");
        font.setPixelSize(16);            
        x = rawk1.replace('Key.','').replace("'",'')[:7]
        
        path.addText(20, 20, font,x)
        path.addText(100, 20, font,str(xing_w.small_txt))
                     
        path.addText(20, 35,font, rawk2.replace('Key.',''));        
        path.addText(100, 35,font, str(xing_w.times));        
        pen = QPen()
        pen.setColor(Qt.white);
        
        pen.setStyle(Qt.SolidLine);
        pen.setWidth(6);        
        painter.setRenderHint(QPainter.Antialiasing);    
        painter.strokePath(path, pen);        
        painter.fillPath(path, QBrush(Qt.black));  
        
    def ont(self):                
        if seek_mode == 7 and show_anchor[0]:            
            self.setGeometry(xing_w.x-50,xing_w.y-50,200,100)
            if self.isHidden():
                self.show()
            if (self.r1,self.r2,self.r3,self.r4)!=(rawk1,rawk2,xing_w.small_txt,xing_w.times):
                (self.r1,self.r2,self.r3,self.r4) = (rawk1,rawk2,xing_w.small_txt,xing_w.times)
                self.update()
            return        
        if not self.isHidden():
            self.hide()        


class my7(QMainWindow):
    def __init__(self,indx=-1):
        super().__init__()   
        self.indx = indx
        self.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint|Qt.ToolTip)
        self.setAttribute(Qt.WA_TranslucentBackground)        
        self.setGeometry(QRect(200,200,100,100))        
        t2 = QTimer(self)
        t2.timeout.connect(self.ont)
        t2.start(10)                
        self.show()
              
    def draw_one(self,p,x,y,color = QColor(180,0,0)):
        pen = QPen()
        pen.setWidth(3)
        pen.setColor(Qt.white)        
        p.setPen(pen)
        p.drawEllipse(QPoint(x,y),7,7)
        
        pen.setWidth(3)
        pen.setColor(color)
        p.setPen(pen)
        p.drawEllipse(QPoint(x,y),6,6)                        
            
    def draw_one2(self,p,x,y,w,h,c=Qt.black):
        x = round(x)
        y = round(y)
        w = round(w)
        h = round(h)
        
        pen = QPen()            
        pen.setWidth(4)
        pen.setColor(Qt.white)        
        p.setPen(pen)
        p.drawRect(x,y,w,h)         
        pen.setWidth(3)
        pen.setColor(c)        
        p.setPen(pen)
        p.drawRect(x,y,w,h)            
        
    def deal51(self,p,x,y,gap):            
        for i in range(4):
            self.draw_one2(p,x-5,y-5+gap*i,10,10)
            continue
                                    
        self.draw_one2(p,x-5,y-5+gap*4,10,10+gap*5)
        for i in range(10,13):            
            self.draw_one2(p,x-5,y-5+gap*i,10,10)            
        
        for i in range(4,10):
            cs = [Qt.black,QColor(250,0,0),QColor(250,250,0),QColor(0,250,0),QColor(0,0,250),Qt.black,]
            pen = QPen()
            pen.setWidth(10)
            pen.setColor(Qt.white)        
            p.setPen(pen)
            p.drawPoint(x,y+gap*i)            
            
            pen.setWidth(7)
            pen.setColor(cs[i-4])        
            p.setPen(pen)
            p.drawPoint(x,y+gap*i)            
            
    def paintEvent(self,e):
        print('my7 paint')
        p = QPainter(self)
        
        if seek_mode ==5:
            xstart = round(scroll_conf[2]/12)+100
            gap = 0            
            cs = [QColor(180,0,0),QColor(220,220,0),QColor(0,180,0),QColor(243,138,207),QColor(153,198,198),QColor(0,0,180),QColor(180,0,0)]
            
            if scroll_back_y>0:
                gap = round(scroll_conf[3]/4/6)*6
                cs.reverse()
            
            if scroll_back_x>0 and scroll_back_y >0:
                self.deal51(p,xstart,20+gap,round(scroll_conf[3]/4/12))
                
            else:            
                for i in range(7):                   
                    self.draw_one(p, xstart,20+round(scroll_conf[3]/4/6)*i+gap,cs[i] )
                    
            cs = [0,QColor(153,198,198),QColor(220,220,0),QColor(243,138,207),QColor(0,180,0),QColor(0,0,180),0]
            if scroll_back_x>0 and scroll_back_y >0:  
                sc = [1,1,0.5,0.3,0]
                sc2 = [0,1.5,1.1,0.2,1]
                cs = [QColor(180,180,0),QColor(0,0,250),QColor(180,0,0), QColor(153,198,198), #QColor(243,138,207),
                      QColor(250,250,0),QColor(250,0,0),QColor(153,158,128),QColor(0,250,0)
                      ]
                
                for i in [1,2,3,4]:
                    self.draw_one2(p, xstart-round(scroll_back_x*scroll_conf[2]/12/5)*i-5,
                               20+round(scroll_conf[3]/4/6)*6+gap-5-round(scroll_conf[3]/4/12)*sc[i],
                               10,10+round(scroll_conf[3]/4/12)*sc[i],cs[i-1] )
                    yg = round(scroll_conf[3]/4)
                    self.draw_one2(p, xstart-round(scroll_back_x*scroll_conf[2]/12/5)*i-5,
                               20+round(scroll_conf[3]/4/6)*6+gap-yg-5,
                               10,10+round(scroll_conf[3]/4/12)*sc2[i],cs[i+3] )
                    
                
            else:
                for i in range(1,6):
                    if scroll_back_y>0:                        
                        self.draw_one(p, xstart-round(scroll_back_x*scroll_conf[2]/12/5)*i-5,20+round(scroll_conf[3]/4/6)*6+gap,cs[i] )
                    else:                    
                        self.draw_one(p, xstart-round(scroll_back_x*scroll_conf[2]/12/5)*i,
                                      20+round(scroll_conf[3]/4/6)*5+gap- round(scroll_conf[3]/4/6)*5,cs[i]  )
                
        else:
            self.draw_one(p, 20,20)
        
        
    def deal_p(self):
        if not show_xy3:
            if not self.isHidden():
                self.hide()     
            return
                
        if seek_mode != 6:
            if not self.isHidden():
                self.hide()        
            return
        ga = screen_move_len[screen_indx][0]*15
        gay = screen_move_len[screen_indx][0]*screen_move_len[screen_indx][2]*19
        if self.indx == 1:
            self.setGeometry(pause_xy_pos[0]-20-ga,pause_xy_pos[1]-20-gay,100,100)
        if self.indx == 2:
            self.setGeometry(pause_xy_pos[0]-20-ga,pause_xy_pos[1]-20+gay,100,100)
        if self.indx == 3:
            self.setGeometry(pause_xy_pos[0]-20+ga,pause_xy_pos[1]-20-gay,100,100)
        if self.indx == 4:
            self.setGeometry(pause_xy_pos[0]-20+ga,pause_xy_pos[1]-20+gay,100,100)
        if self.isHidden():
            self.show()            

    def ont(self):                  
        if self.indx!=-1:
            return self.deal_p()
        
        if not show_xy2:
            if not self.isHidden():
                self.hide()     
            return
                
        if seek_mode == 5 and sc_draw: 
            gap = 100
            xstart = round(scroll_conf[2]/12)+100
            
            if scroll_back_y>0:
                gap = 99
            g = self.geometry()
            x,y,w,h = g.x(),g.y(),g.width(),g.height()
            if (x,y,w,h) != (sc_draw[0]+round(scroll_back_x*scroll_conf[2]/12)-xstart,
                             sc_draw[1]+round(-1*scroll_conf[3]/4)-20,
                             gap+xstart,gap+round(scroll_conf[3]/2)
                             ):
            
                self.setGeometry(sc_draw[0]+round(scroll_back_x*scroll_conf[2]/12)-xstart,
                             sc_draw[1]+round(-1*scroll_conf[3]/4)-20,
                             gap+xstart,gap+round(scroll_conf[3]/2)
                             )            
                self.update()
            if self.isHidden():
                self.show()
            return             
        if not self.isHidden():
            self.hide()        

               
a = QApplication([])   

w2 = my2()#矩形框
w = my(w2)#放大
w3 = my3(w)#操作界面
w5 = my4(2)#画鼠标
w4 = my4(1,w5)#画鼠标
w_rec_1 = my42([1,1])#鼠标外围
w_rec_2 = my42([1,-1])
w_rec_3 = my42([-1,-1])
w_rec_4 = my42([-1,1])

w6 = my5()#托盘
w7 = my6()#定位圆圈
w_xing = my66()#定位圆圈
w7_2 = my7()#定位圆圈，右下
w8_1 = my7(1)
w8_2 = my7(2)
w8_3 = my7(3)
w8_4 = my7(4)

from xy_pos import my77
w8 = my77(screen_config,1,is_type2, has_r_win, False,True) #全局定位
w9 = my77(screen_config,2,is_type2, has_r_win, False,True) #全局定位
w10 = my77(screen_config,8,is_type2, has_r_win, False,True) #全局定位
for i in screen_config:
    x,y,w,h = i
    mydingL.append(myding(x,y,w,h))
a.exec_()
